for i := 0; i < sweeps; i++ {
s = laplace.Operator(shift, mass, nn)
prodDot = DotProd(shift, s)
shiftScale = dotProd/prodDot
for k, sk := range s {
phi[k] += shiftScale * shift[k]
rho[k] -= shiftScale * sk
}
prodDot = DotProd(rho, rho)
fmt.Println(i, math.Sqrt(prodDot/rel))
if math.Sqrt(prodDot/rel) < tol {
return phi
}
scaleShift = prodDot/dotProd
for k, rhok := range rho {
shift[k] = rhok + scaleShift * shift[k]
}
dotProd = prodDot
}
(full code see at the end)
my first version was using s:=laplace.. and prodDot:=DotProd..
and so on, but that's about the same ...
Thank you, best regards, Yoshi
package main
import (
"fmt"
"./gridgeom"
"./laplace"
"math"
"os"
"rand"
)
func main() {
ndim := 4
lsize := make([]int, ndim + 1)
for i, _ := range lsize {
lsize[i] = 31
}
nn, cols, nvol := gridgeom.PeriodicBound(lsize, ndim)
if len(nn) < ndim {
fmt.Fprintf(os.Stderr, "error: gridgeom.PeriodicBound() no next neighbor field\n")
os.Exit(1)
}
// Field initialisation
rho := make([]float64, nvol)
for i := 0; i < nvol; i++ {
if nn[i*cols] == 1 {
rho[i] = rand.NormFloat64()
}
}
fmt.Printf("set terminal png\nset output 'convergence.png'\nset title '%v%s %v %s'\nset logscale y\nplot '-'\n", ndim, "D grid with", nvol, "points")
phi := ConjGrad(rho, nn, 0, 10E-14)
if len(phi) < ndim {
fmt.Fprintf(os.Stderr, "error: lineq.ConjGrad() did not converge\n")
os.Exit(1)
}
}
func ConjGrad(rho []float64, nn []int, mass, tol float64) []float64 {
var prodDot, shiftScale, scaleShift float64
sweeps := 10000
nvol := len(rho)
s := make([]float64, nvol)
shift := make([]float64, nvol)
phi := make([]float64, nvol)
copy(shift, rho)
dotProd := DotProd(rho, rho)
rel := dotProd
for i := 0; i < sweeps; i++ {
s = laplace.Operator(shift, mass, nn)
prodDot = DotProd(shift, s)
shiftScale = dotProd/prodDot
for k, sk := range s {
phi[k] += shiftScale * shift[k]
rho[k] -= shiftScale * sk
}
prodDot = DotProd(rho, rho)
fmt.Println(i, math.Sqrt(prodDot/rel))
if math.Sqrt(prodDot/rel) < tol {
return phi
}
scaleShift = prodDot/dotProd
for k, rhok := range rho {
shift[k] = rhok + scaleShift * shift[k]
}
dotProd = prodDot
}
return make([]float64, 1)
}
func DotProd(x, y []float64) (res float64) {
for i, xi := range x {
res += xi*y[i]
}
return
}
================================================
package gridgeom
func PeriodicBound(lsize []int, ndim int) ([]int, int, int) {
if len(lsize) != ndim + 1 {
return make([]int, 0), 0, 0
}
ibase := make([]int, ndim + 2)
ibase[1] = 1
for k := 1; k <= ndim; k++ {
ibase[k + 1] = ibase[k]*lsize[k]
}
nvol := ibase[ndim + 1]
ix := make([]int, ndim + 1)
for i, _ := range ix {
ix[i] = 0
}
cols := ndim*2 + 1
nn := make([]int, nvol*cols)
for i := 0; i < nvol; i++ {
nn[i*cols] = 1
}
for i := 0; i < nvol; i++ {
irow := i*cols
for k := 1; k <= ndim; k++ {
nn[irow + k] = i + ibase[k]
if ix[k] == (lsize[k] - 1) {
nn[irow + k] -= ibase[k + 1]
nn[irow] = 0
}
nn[irow + k + ndim] = i - ibase[k]
if ix[k] == 0 {
nn[irow + k + ndim] += ibase[k + 1]
nn[irow] = 0
}
}
for k := 1; k <= ndim; k++ {
ix[k]++
if ix[k] < lsize[k] {
break
}
ix[k] = 0
}
}
return nn, cols, nvol
}
======================================================
package laplace
func Operator(phi []float64, mass float64, nn []int) []float64 {
nvol := len(phi)
cols := len(nn)/nvol
phiout := make([]float64, nvol)
scale := mass * mass + float64(cols - 1)
for i := 0; i < nvol; i++ {
if nn[i*cols] == 0 {
// Dirichlet
phiout[i] = 0
} else {
phiout[i] = phi[i] * scale
for k := 1; k < cols; k++ {
phiout[i] -= phi[nn[i*cols + k]]
}
}
}
return phiout
}
Strange, I have 500MB memory (something like 190MB free) on slackware 13.0 32bit
It stops at something like 90 1e-7.
I use:
export GOROOT=$HOME/go
export GOARCH=386
export GOOS=linux
export GOBIN=$HOME/755
hg id: f776656df34c
Best regards, Yoshi
I think my C version works a bit like that, I am still unsure about
that slice thing ...
Best regards, Yoshi
;::::::::::::::::::::::: Olreich :
I filed the results of my tests as: Issue 909: GOARCH=386 Garbage
Collection Is Ineffectual: mmap: errno=0xc
http://code.google.com/p/go/issues/detail?id=909
Peter
Thank you very much Peter!
Best regards, Yoshi
original code:
i 569; Alloc 4240432608; TotalAlloc 4408242120
i 570; Alloc 4247858704; TotalAlloc 4415960056
i 571; Alloc 4255284800; TotalAlloc 4423677992
mmap: errno=0xc
with runtime.GC() inside the for loop:
i 996; Alloc 289776696; TotalAlloc 7668478936
i 997; Alloc 289776696; TotalAlloc 7676160008
i 998; Alloc 289776696; TotalAlloc 7683841080
i 999; Alloc 289776696; TotalAlloc 7691522152
end; Alloc 282387512; TotalAlloc 7691814040