Declaring types in Go for a sample gonum application - go

Being an ardent fan of numpy, I was pleased to discover that a library for golang was in progress. I wrote a small test program, based heavily on the documentation, that looks like the following:
package main
import (
"fmt"
"math"
"gonum.org/v1/gonum/stat"
)
func main() {
xs := []float64 {
23.32, 44.32, 100.12, 191.90,
23.22, 90.21, 12.22, 191.21,
1.21, 12.21, 34.23, 91.02,
}
variance := stat.Variance(xs)
fmt.Printf("Data: %v\n", xs)
stddev := math.Sqrt(variance)
fmt.Printf("Standard deviation: %d\n\n", stddev)
}
When I attempted to build the program, I noticed the following compiler error:
C:\>go build hello.go
# command-line-arguments
.hello.go:19:30: not enough arguments in call to stat.Variance
have ([]float64)
want ([]float64, []float64)
Any advice would be most appreciated.
Thank you.

stat.Variance expects two parameters of type []float64 of the same length:
func Variance(x, weights []float64) float64
You are missing the weights parameter.
You can pass nil as the second parameter of stat.Variance function if you wants to set all the weights of the random variables to 1.
stat Package Documentation

Related

Deep equal on function value

From reflect package, I use DeepEqual function check similarity of both value. It works until I use function as value.
package main
import "fmt"
import "reflect"
type thisHandler func(s string)
func main() {
var a thisHandler = func(s string) {
fmt.Println(s)
}
b := a
c := a
fmt.Println(b)
fmt.Println(c)
fmt.Println(reflect.DeepEqual(b,c))
}
Playground
Why can't DeepEqual check similarity of value of a function?
Based on it's documentation said:
https://golang.org/pkg/reflect/#DeepEqual
...
Func values are deeply equal if both are nil; otherwise they are
not deeply equal.
...
In general DeepEqual is a recursive relaxation
of Go's == operator. However, this idea is impossible to implement
without some inconsistency. Specifically, it is possible for a value
to be unequal to itself, either because it is of func type
(uncomparable in general)...

How to get the natural log of a big integer

I am trying to convert a string to integer and then to calculate its log.
My first approach was to convert the string using strconv library, but I got an error about the length of the string to be converted.
After that, I used math/big library which worked fine. Now I am not able to apply math.Log()on the resulted big integer.
Code:
package main
import (
"fmt"
"math"
"math/big"
)
func main() {
bb := "11948904162160164791281681976941230184120142151411311314211115130161285142991119211447"
bi := big.NewInt(0)
if _, ok := bi.SetString(bb, 10); ok {
fmt.Println(math.Log(bi))
} else {
fmt.Printf("error parsing line %#v\n", bb)
}
}
Error:
cannot use bi (type *big.Int) as type float64 in argument to math.Log
There are very few situations in which you'd need a precision greater than the one provided by the standard float64 type.
But just to satisfy any "midnight crazy ideas" (or even some very in-depth scientific research!) anyone might run into, Rob Pike's implementations of some operations with big floats are probably the best you can get right now with Go. The log function can be found here.

Using crypto/rand for generating permutations with rand.Perm

Go has two packages for random numbers:
crypto/rand, which provides a way to get random bytes
math/rand, which has a nice algorithm for shuffling ints
I want to use the Perm algorithm from math/rand, but provide it with high-quality random numbers.
Since the two rand packages are part of the same standard library there should be a way to combine them in a way so that crypto/rand provides a good source of random numbers that is used by math/rand.Perm to generate a permutation.
Here (and on the Playground) is the code I wrote to connect these two packages:
package main
import (
cryptoRand "crypto/rand"
"encoding/binary"
"fmt"
mathRand "math/rand"
)
type cryptoSource struct{}
func (s cryptoSource) Int63() int64 {
bytes := make([]byte, 8, 8)
cryptoRand.Read(bytes)
return int64(binary.BigEndian.Uint64(bytes) >> 1)
}
func (s cryptoSource) Seed(seed int64) {
panic("seed")
}
func main() {
rnd := mathRand.New(&cryptoSource{})
perm := rnd.Perm(52)
fmt.Println(perm)
}
This code works. Ideally I don't want to define the cryptoSource type myself but just stick together the two rand packages so that they work together. So is there a predefined version of this cryptoSource type somewhere?
That's basically what you need to do. It's not often that you need a cryptographically secure source of randomness for the common usage of math/rand, so there's no adaptor provided. You can make the implementation slightly more efficient by allocating the buffer space directly in the value, rather than allocating a new slice on every call. However in the unlikely event that reading the OS random source fails, this will need to panic to prevent returning invalid results.
type cryptoSource [8]byte
func (s *cryptoSource) Int63() int64 {
_, err := cryptoRand.Read(s[:])
if err != nil {
panic(err)
}
return int64(binary.BigEndian.Uint64(s[:]) & (1<<63 - 1))
}

Turning []interface{} into arguments to a non-variadic function

I am looking for an elegant way to unzip a list of arguments in Go. I do not want to use a variadic function for that purpose because in my usecase when writing a function I already know the number of arguments and I want to keep that part simple. However in my usecase the parameters arrive as []interface{}.
I could not find a solution but hey maybe someone out there already knows how to do that?
package main
import (
"fmt"
)
// NON-VARIADIC greater
func greet(n1, n2 string) {
fmt.Printf("%s %s\n", n1, n2)
}
func main() {
l := []interface{}{"hello", "world"}
// works
greet(l[0].(string), l[1].(string))
// does not work: "./args.go:20: not enough arguments in call to greet"
//greet(l...)
// is there something more elegant to unzip the list?
}
You could create a "generic" caller using reflect package, although this comes with overhead and lacks type safety. Unless you have some special case situation and don't know what you want to call in the code, it would be wiser to use the snippet from your question which works, but you consider not elegant.
Example usage of reflect which could be your starting point:
package main
import (
"fmt"
"reflect"
)
func call(f interface{}, args []interface{}) {
// Convert arguments to reflect.Value
vs := make([]reflect.Value, len(args))
for n := range args {
vs[n] = reflect.ValueOf(args[n])
}
// Call it. Note it panics if f is not callable or arguments don't match
reflect.ValueOf(f).Call(vs)
}
func greet(n1, n2 string) {
fmt.Printf("%s %s\n", n1, n2)
}
func main() {
l := []interface{}{"hello", "world"}
call(greet, l)
}
// Output: hello world
https://play.golang.org/p/vbi3CChCdV
I'm not quite sure what you're trying to do. If you want a way to easily pass a slice of two empty interfaces to a function that accepts two strings, you can create a little helper:
func twoStrings(vs []interface{}) (string, string) {
return vs[0].(string), vs[1].(string)
}
Use it as
greet(twoStrings(l))
Playground: http://play.golang.org/p/R8KFwMUT_V.
But honestly, it seems like you're doing something wrong, trying to make the Go type system to do something it cannot do.

Evaluate formula in Go

Using Go (golang) I'd like to take a string with a formula and evaluate it with pre-defined values. Here's a way to do it with python's parser module:
x = 8
code = parser.expr("(x + 2) / 10").compile()
print eval(code)
# prints 1
Any idea how to do it with Go?
This package will probably work for your needs: https://github.com/Knetic/govaluate
expression, err := govaluate.NewEvaluableExpression("(x + 2) / 10");
parameters := make(map[string]interface{}, 8)
parameters["x"] = 8;
result, err := expression.Evaluate(parameters);
You will probably need to resort to a library that interprets math statements or have to write your own parser. Python being a dynamic language can parse and execute python code at runtime. Standard Go cannot do that.
If you want to write a parser on your own, the go package will be of help. Example (On play):
import (
"go/ast"
"go/parser"
"go/token"
)
func main() {
fs := token.NewFileSet()
tr, _ := parser.ParseExpr("(3-1) * 5")
ast.Print(fs, tr)
}
The resulting AST (Abstract Syntax Tree) can then be traversed and interpreted as you choose (handling '+' tokens as addition for the now stored values, for example).
I have made my own equation evaluator, using Djikstra's Shunting Yard Algorithm.
It supports all operators, nested parenthesis, functions and even user defined variables.
It is written in pure go
https://github.com/marcmak/calc
go-exprtk package will probably meet all kinds of your needs to evaluate any kind of mathematical expression dynamically.
package main
import (
"fmt"
"github.com/Pramod-Devireddy/go-exprtk"
)
func main() {
exprtkObj := exprtk.NewExprtk()
exprtkObj.SetExpression("(x + 2) / 10")
exprtkObj.AddDoubleVariable("x")
exprtkObj.CompileExpression()
exprtkObj.SetDoubleVariableValue("x", 8)
fmt.Println(exprtkObj.GetEvaluatedValue())
}
This package has many capabilities
There is no such module in Go. You have to build your own. You could use subpackages of the go package, but they might be overkill for your application.
For expression or program evaluation, you can build a lexer and parser using lex and yacc, and specify exactly the syntax and semantics of your mini-language. A calculator has always been a standard yacc example, and the go versions of lex and yacc are no different.
Here's a pointer to the calc example: https://github.com/golang-samples/yacc/tree/master/simple
With this code you can evaluate dynamically any formula and return true or false:
package main
import (
"go/token"
"go/types"
)
func main() {
fs := token.NewFileSet()
tv, err := types.Eval(fs, nil, token.NoPos, "(1 + 4) >= 5")
if err != nil {
panic(err)
}
println(tv.Value.String())
}
There's nothing built in that could do that (remember, Go is not a dynamic language).
However, you can always use bufio.Scanner and build your own parser.
Googling around I found this: https://github.com/sbinet/go-eval
It appears to be an eval loop for Go.
go get github.com/sbinet/go-eval/cmd/go-eval
go install github.com/sbinet/go-eval/cmd/go-eval
go-eval

Resources