"declared and not used" Error - go

I get this error saying that I'm not using a variable… but to my noob eyes, it looks like I am:
func Sqrt(x float64) float64 {
z := float64(x);
for i := 0; i < 10; i++ {
z := z - (z*z - x) / (2 * z);
}
return z;
}
Can anyone point out what I'm missing about the language? I think it has to do with = vs. := and scoping, but I'm not sure.

The := in your for-loop declares a new variable z which shadows the outer z. Turn it into a plain = to fix the problem.
func Sqrt(x float64) float64 {
z := x
for i := 0; i < 10; i++ {
z = z - (z*z - x) / (2 * z);
}
return z;
}
By the way, for equal precision and a bit more speed you could try the following implementation which does two of your steps at once:
func Sqrt(x float64) float64 {
z := x
for i := 0; i < 5; i++ {
a := z + x/z
z = a/4 + x/a
}
return z
}

Here is another way to look at the function
func Sqrt(x float64) (z float64) {
z = x
for i := 0; i < 10; i++ {
z = z - (z*z - x)/(2*z);
}
return
}

Related

parallelism in Golang loop

I have a project and need to run it on multiple cores of an cpu to get more speed . I have used omplib in fortran but I am not familiar with Golang parallelism . I tried goroutines but that went wrong and made a mess and I got false results. This is my code :
package main
import (
"bufio"
"fmt"
"log"
"math"
"math/rand"
"os"
"time"
)
const (
n_particles int = 2048
n_steps int = 1000000
dt float64 = 1.0
v0 float64 = 0.50
radius float64 = 1.0
f_intensity float64 = 1.8
scale float64 = 32.0
alpha float64 = 1.0 / 36.0
)
var (
x [n_particles + 1]float64
y [n_particles + 1]float64
angles [n_particles + 1]float64
vx [n_particles + 1]float64
vy [n_particles + 1]float64
order [n_steps + 1]float64
)
func main() {
/////randomizer
vstart := time.Now()
rsource := rand.NewSource(time.Now().UnixNano())
randomizer := rand.New(rsource)
for i := 0; i <= n_particles; i++ {
x[i] = (randomizer.Float64()) * scale
y[i] = (randomizer.Float64()) * scale
angles[i] = (randomizer.Float64()) * math.Pi * 2
sin, cos := math.Sincos(angles[i])
vx[i] = v0 * cos
vy[i] = v0 * sin
}
//////main loop
for i := 0; i <= n_steps; i++ {
start := time.Now()
for j := 0; j <= n_particles; j++ {
x[j] = x[j] + (vx[j] * dt)
//x[j] = math.Mod(x[j], scale)
if x[j] < 0.0 {
x[j] = x[j] + scale
}
if x[j] >= scale {
x[j] = x[j] - scale
}
y[j] = y[j] + (vy[j] * dt)
//y[j] = math.Mod(x[j], scale)
if y[j] < 0.0 {
y[j] = y[j] + scale
}
if y[j] >= scale {
y[j] = y[j] - scale
}
}
type intpos struct {
x, y int64
}
adjacencyIndex := make(map[intpos][]int)
////getting each boxes particles
for j := 0; j <= n_particles; j++ {
// . . .
ix, iy := int64(math.Floor(x[j])), int64(math.Floor(y[j])) // getting particle box
adjacencyIndex[intpos{ix, iy}] = append(adjacencyIndex[intpos{ix, iy}], j) // adding particles to boxes
}
/////////
m_angles := angles
Now I want following loop run in parallel :
////particle loop - I WANT FOLLOWING LOOP PARALLEL
for j := 0; j <= n_particles; j++ {
sumanglesx := 0.0
sumanglesy := 0.0
ix, iy := int64(math.Floor(x[j])), int64(math.Floor(y[j]))
// fxi = math.Floor(x[j])
// fyi = math.Floor(y[j])
for dx := -1; dx <= 1; dx++ {
for dy := -1; dy <= 1; dy++ {
adjacentParticles := adjacencyIndex[intpos{ix + int64(dx), iy + int64(dy)}]
for _, k := range adjacentParticles {
dist := ((x[k] - x[j]) * (x[k] - x[j])) + ((y[k] - y[j]) * (y[k] - y[j]))
if dist < radius {
sy, sx := math.Sincos(angles[k])
if k <= j {
sumanglesx = sumanglesx + sx
sumanglesy = sumanglesy + sy
} else {
sx = alpha * sx
sy = alpha * sy
sumanglesx = sumanglesx + sx
sumanglesy = sumanglesy + sy
}
}
}
}
}
bsource := rand.NewSource(time.Now().UnixNano())
bandomizer := rand.New(bsource)
sumanglesy = sumanglesy
sumanglesx = sumanglesx
r_angles := math.Atan2(sumanglesy, sumanglesx)
}
}
}
I specified one loop which should run parallelly .
Here are two approaches to try out: https://play.golang.org/p/O1uB2zzJEC5
package main
import (
"fmt"
"sync"
)
func main() {
waitGroupApproach()
channelApproach()
}
func waitGroupApproach() {
fmt.Println("waitGroupApproach")
var waitgroup sync.WaitGroup
result_table := make([]int, 6, 6)
for j := 0; j <= 5; j++ {
waitgroup.Add(1)
go func(index int) {
fmt.Println(index) // try putting here `j` instea of `index`
result_table[index] = index*2
waitgroup.Done()
}(j) // you have to put any for-loop variables into closure
// because otherwsie all routines inside will likely get the last j == n_particles + 1
// as they will likely run after the loop has finished
}
fmt.Println("waiting")
waitgroup.Wait()
// process results further
fmt.Println("finished")
fmt.Println(result_table)
}
func channelApproach() {
fmt.Println("\nchannelApproach")
type intpos struct {
x, y, index int
}
results := make(chan intpos)
// initialize routines
for j := 0; j <= 5; j++ {
go func(index int) {
// do processing
results <- intpos{index*2, index*3, index}
}(j)
}
fmt.Println("Waiting..")
// collect results, iterate the same number of times
result_table := make([]int, 6)
for j := 0; j <= 5; j++ {
r := <- results
// watch out order, migth not be the same as in invocation,
// so that's why I store j in results as well
fmt.Println(r.index, r.x, r.y)
result_table[r.index] = r.x
}
fmt.Println("Finished..")
fmt.Println(result_table)
}
I prefer the channel approach because it's more go idiomatic to me and it allows to easier handle panic, error conditions, etc.

Go tour #18. How do I pass in integers to Pic?

The following code errors with index out of range. I tried modifying main to
pic.Show(Pic(500, 500)) but that changes the argument from function to the return type and it fails to compile. How do I pass in integers if the pic.Show is expecting a function as an argument.
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
mypic := [][]uint8{}
for y := 0; y < dy; y++ {
mypic[y] = []uint8{}
for x := 0; x < dx; x++ {
mypic[y][x] = uint8((x + y) / 2)
}
}
return mypic
}
func main() {
pic.Show(Pic)
}
You don't. The Go Tour program will pass Pic test values to your program. Your problem is in your code: panic: runtime error: index out of range. [][]uint8{} and []uint8{} allocate zero y and zero x slice elements. Use make to allocate your y and x slices. For example,
package main
import "golang.org/x/tour/pic"
func Pic(dx, dy int) [][]uint8 {
pixels := make([][]uint8, dy)
for y := 0; y < dy; y++ {
pixels[y] = make([]uint8, dx)
for x := 0; x < dx; x++ {
pixels[y][x] = uint8((x + y) / 2)
}
}
return pixels
}
func main() {
pic.Show(Pic)
}
Reference: Making slices, maps and channels, The Go Programming Language Specification

How does one count a number of iterations with Go?

So I have this small piece of code that iterates as long as needed until the difference between the value sought after is abysmal. I want to count and print the number of iterations after the code is done running and preferably in my main function (along with printing everything else I need).
Edit: Okay, I've managed to do it like this. I wonder if there's an easier way of counting the iterations and passing them to the output function.
func sqrt(x float64) (float64, int) {
k := 1
z := 1.0
q := (z*z - x)/(2*z)
for {
if math.Abs(-q) > 0.001 {
z -= q
q = (z*z - x)/(2*z)
k += 1
} else {
break
}
}
return z, k
}
func main() {
k := 1
z := 1.0
z, k = sqrt(9)
fmt.Println("Your sqrt = ", z)
fmt.Println("Math Sqrt = ",math.Sqrt(9))
fmt.Println("Iterations: ", k)
}
You can return your float value and an int (as the number of iterations). I made very minor revision to your example to demonstrate.
func sqrt(x float64) (float64, int) {
z := 1.0
i := 1
q := (z*z - x) / (2 * z)
for {
if math.Abs(-q) > 0.01 {
i++
z -= q
q = (z*z - x) / (2 * z)
} else {
break
}
}
return z, i
}
func main() {
f, i := sqrt(9)
fmt.Printf("result: %f iterations: %d\n", f, i)
fmt.Println(math.Sqrt(9))
}
You can provide multiple return values through your function:
func main() {
numLoops, newNum := sqrt(9)
}
func sqrt(x float64) (int, float64) {
<implementation>
}
GoPlay here: https://play.golang.org/p/R2lV41EbEd

Processing: Image with rounded corners

I'm drawing a section of an image, however I'd like to apply rounded corners to it. I can't find any way of doing this.
In the draw() method:
img_section = img.get(gaze_x, gaze_y, gaze_size_x, gaze_size_y);
image(img_section, gaze_x, gaze_y);
You could copy the image and then manually set the corner pixels using the set() function.
You could just draw a rounded rectangle around the image- if the image will be placed on a background with a single color, just draw a rounded rectangle with the same color as the image.
Or you could come up with an image mask and draw that on top of your image.
package utils
import (
"ddkt365-poster/library/log"
"image"
"image/color"
"math"
)
// Settable Settable
type Settable interface {
Set(x, y int, c color.Color)
}
var empty = color.RGBA{255, 255, 255, 0}
// Convert Convert
func Convert(m *image.Image, rate float64) {
b := (*m).Bounds()
w, h := b.Dx(), b.Dy()
r := (float64(min(w, h)) / 2) * rate
log.Error("bounds:%v", r)
sm, ok := (*m).(Settable)
if !ok {
// Check if image is YCbCr format.
ym, ok := (*m).(*image.YCbCr)
if !ok {
log.Error("errInvalidFormat")
return
}
*m = yCbCrToRGBA(ym)
sm = (*m).(Settable)
}
// Parallelize?
for y := 0.0; y <= r; y++ {
l := math.Round(r - math.Sqrt(2*y*r-y*y))
for x := 0; x <= int(l); x++ {
sm.Set(x-1, int(y)-1, empty)
}
for x := 0; x <= int(l); x++ {
sm.Set(w-x, int(y)-1, empty)
}
for x := 0; x <= int(l); x++ {
sm.Set(x-1, h-int(y), empty)
}
for x := 0; x <= int(l); x++ {
sm.Set(w-x, h-int(y), empty)
}
}
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func yCbCrToRGBA(m image.Image) image.Image {
b := m.Bounds()
nm := image.NewRGBA(b)
for y := 0; y < b.Dy(); y++ {
for x := 0; x < b.Dx(); x++ {
nm.Set(x, y, m.At(x, y))
}
}
return nm
}
// Image with rounded corners (Go image/draw package)
if i.BorderRadius > 0 {
utils.Convert(&img, (float64(i.BorderRadius) / 100))
}
draw.Draw(canvs, img.Bounds().Add(image.Pt(i.X, i.Y)), img, image.ZP, draw.Over)

difference between declaring variables with var vs without var in go

I was having some trouble with step 35 in the tour of Go exercise.
Here's what my code looks like:
package main
import "code.google.com/p/go-tour/pic"
func Pic(dx, dy int) [][]uint8 {
var pic = make([][]uint8, dy)
for y := 0; y < dy; y++ {
pic[y] = make([]uint8, dx)
for x := 0; y < dx; x++ {
pic[y][x] = uint8(x*y)
}
}
return pic
}
When looking for a solution, I found PeterSO's code which works perfectly
func main() {
pic.Show(Pic)
}
func Pic(dx, dy int) [][]uint8 {
pixels := make([][]uint8, dy)
for y := 0; y < dy; y++ {
pixels[y] = make([]uint8, dx)
for x := 0; x < dx; x++ {
pixels[y][x] = uint8(x * y)
}
}
return pixels
}
The only difference I can see, is that I'm defining the pic variable using the var keyword whereas his code is using the := assignment. Now, why does my code not work?
You wrote
for x := 0; y < dx; x++ {
pic[y][x] = uint8(x * y)
}
in particular: y < dx, which causes,
panic: runtime error: index out of range
I wrote
for x := 0; x < dx; x++ {
pixels[y][x] = uint8(x * y)
}
in particular: x < dx. Therefore, change your y to x.
package main
import "code.google.com/p/go-tour/pic"
func Pic(dx, dy int) [][]uint8 {
var pic = make([][]uint8, dy)
for y :=0; y < dy; y++ {
pic[y] = make([]uint8, dx)
for x :=0; x<dx; x++ {
pic[y][x] = uint8(x*y)
}
}
return pic
}
func main() {
pic.Show(Pic)
}
http://play.golang.org/p/UvGgszFhl-
Variable declarations
A variable declaration creates a variable, binds an identifier to it
and gives it a type and optionally an initial value.
VarDecl = "var" ( VarSpec | "(" { VarSpec ";" } ")" ) .
VarSpec = IdentifierList ( Type [ "=" ExpressionList ] | "=" ExpressionList ) .
Short variable declarations
A short variable declaration uses the syntax:
ShortVarDecl = IdentifierList ":=" ExpressionList .
It is a shorthand for a regular variable declaration with initializer
expressions but no types:
"var" IdentifierList = ExpressionList .
Unlike regular variable declarations, a short variable declaration may
redeclare variables provided they were originally declared earlier in
the same block with the same type, and at least one of the non-blank
variables is new.
In your code var pic = make([][]uint8, dy) and the short form pic := make([][]uint8, dy) will both work.
If you use the :=, the type of the variable is implied from the expression on the right of the sign. If you use =, no assumption is made and you need to specify the type yourself.
In this case, you should write it like this:
var pic [][]uint8 = make([][]uint8, dy)
but this is indeed better because shorter and as clear:
pic := make([][]uint8, dy)

Resources