Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Struct And Simulation Uebung 2 Monte Carlo
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Torda, Prof. Dr. Andrew Ernest
Struct And Simulation Uebung 2 Monte Carlo
Commits
bd7dd92b
Commit
bd7dd92b
authored
4 years ago
by
Andrew E. Torda
Browse files
Options
Downloads
Patches
Plain Diff
Moved plotting into a separate file.
Removed buffering of stdout. This is for students to read, rather than speed.
parent
4d3e2e81
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
pi.go
+17
-107
17 additions, 107 deletions
pi.go
with
17 additions
and
107 deletions
pi.go
+
17
−
107
View file @
bd7dd92b
// 29 april 2021
//
If I get time, it would be fun to do
the second
u
ebung in
go
.
//
An example for
the second
U
ebung in
Struktur und Simulation
.
// For the sake of speed, we can do all the numbers at once, put
// them in arrays, rather than doing i/o on every step.
// them in arrays, rather than doing i/o on every step. This is actually
// necessary if we want to make plots. We have to store all the points.
// The plotting library I used does not draw to the screen. Bummer. One could
// use the canvas in vggio, although that pulls in all of fyne.
// use the canvas in vggio, although that pulls in all of the fyne library.
// There is an egregious bug in the clipping of lines in plotter, so do
// not use it. Use a scatter plot.
package
main
import
(
"bufio"
"errors"
"flag"
"fmt"
...
...
@@ -16,13 +18,6 @@ import (
"math/rand"
"os"
"strconv"
"gonum.org/v1/plot"
"gonum.org/v1/plot/font"
"gonum.org/v1/plot/plotter"
"gonum.org/v1/plot/vg"
"gonum.org/v1/plot/vg/draw"
"gonum.org/v1/plot/vg/vgimg"
)
const
(
...
...
@@ -30,18 +25,12 @@ const (
exitFailure
)
const
(
sizeHrznt
font
.
Length
=
15
*
vg
.
Centimeter
sizeVert
font
.
Length
=
10
*
vg
.
Centimeter
nPointPlot
=
1000
)
func
breaker
(
x
interface
{})
{}
// usage prints out anything the caller gives us then bails.
func
usage
(
e
string
)
{
u
:=
"usage: pi seed nsteps nstep_nprint"
u
:=
"usage: pi [flags] seed nsteps nstep_nprint"
if
e
!=
""
{
fmt
.
Fprintln
(
os
.
Stderr
,
e
+
"
\n
"
+
u
)
}
flag
.
Usage
()
os
.
Exit
(
exitFailure
)
}
...
...
@@ -60,7 +49,7 @@ func getnums(cmdArgs cmdArgs) ([]float32, []float32) {
}
}
if
inPoint
[
0
]
{
inCnt
[
0
]
=
1
inCnt
[
0
]
=
1
// avoid divide by zero errors in loop
}
for
i
:=
1
;
i
<
cmdArgs
.
nstep
;
i
++
{
inCnt
[
i
]
=
inCnt
[
i
-
1
]
...
...
@@ -73,98 +62,20 @@ func getnums(cmdArgs cmdArgs) ([]float32, []float32) {
stdErr
:=
make
([]
float32
,
cmdArgs
.
nstep
)
// standard error
for
i
:=
range
inCnt
{
ptmp
:=
float64
(
inCnt
[
i
])
/
float64
(
i
+
1
)
// do we need more precision ?
qtmp
:=
1
-
ptmp
ptmp
:=
float64
(
inCnt
[
i
])
/
float64
(
i
+
1
)
pi
[
i
]
=
float32
(
4
*
ptmp
)
stdErr
[
i
]
=
float32
(
4
*
math
.
Sqrt
((
ptmp
*
q
tmp
)
/
(
float64
(
i
+
1
))))
stdErr
[
i
]
=
float32
(
4
*
math
.
Sqrt
((
ptmp
*
(
1
-
p
tmp
)
)
/
(
float64
(
i
+
1
))))
}
return
pi
,
stdErr
}
// wrtTable prints out the table, as per the Uebung instructions
func
wrtTable
(
cmdArgs
cmdArgs
,
pi
,
stdErr
[]
float32
)
{
b
:=
bufio
.
NewWriter
(
os
.
Stdout
)
b
.
WriteString
(
fmt
.
Sprintf
(
"%8s %7s %7s %7s
\n
"
,
"step"
,
"pi"
,
"err"
,
"stderr"
))
defer
b
.
Flush
()
fmt
.
Printf
(
"%8s %7s %7s %7s
\n
"
,
"step"
,
"pi"
,
"err"
,
"stderr"
)
for
i
:=
0
;
i
<
cmdArgs
.
nstep
;
i
=
i
+
cmdArgs
.
nstepPrint
{
e
:=
math
.
Pi
-
pi
[
i
]
b
.
WriteString
(
fmt
.
Sprintf
(
"%8d %.5f %.5f %.5f
\n
"
,
i
+
1
,
pi
[
i
],
e
,
stdErr
[
i
]))
}
}
// addline saves us doing the same point copying, adding three times.
func
oneplot
(
y
[]
float32
)
(
*
plot
.
Plot
,
error
)
{
p
:=
plot
.
New
()
points
:=
make
(
plotter
.
XYs
,
len
(
y
))
for
i
,
piV
:=
range
y
{
points
[
i
]
=
plotter
.
XY
{
X
:
float64
(
i
+
1
),
Y
:
float64
(
piV
)}
}
if
line
,
err
:=
plotter
.
NewLine
(
points
);
err
!=
nil
{
return
nil
,
err
}
else
{
line
.
LineStyle
.
Width
=
4
p
.
Add
(
line
)
fmt
.
Printf
(
"%8d %.5f %.5f %.5f
\n
"
,
i
+
1
,
pi
[
i
],
e
,
stdErr
[
i
])
}
return
p
,
nil
}
// doplot makes a primitive plot without any interesting options
// If no plotname is given, it means no plot is wanted. We have to rewrite the data
// to fit to the plot function's expectations (x/y pairs).
func
doplot
(
pi
,
stdErr
[]
float32
,
plotName
string
)
error
{
if
plotName
==
""
{
return
nil
}
const
step
=
"step"
pPi
,
err
:=
oneplot
(
pi
)
// pi estimate
if
err
!=
nil
{
return
err
}
pPi
.
Title
.
Text
=
""
pPi
.
X
.
Label
.
Text
=
step
pPi
.
Y
.
Label
.
Text
=
"π estimate"
pStd
,
err
:=
oneplot
(
stdErr
)
// std error
if
err
!=
nil
{
return
err
}
pStd
.
Title
.
Text
=
""
pStd
.
X
.
Label
.
Text
=
step
pStd
.
Y
.
Label
.
Text
=
"std error"
pAbs
:=
plot
.
New
()
{
tmperr
:=
make
([]
float32
,
len
(
pi
))
// the extra bracing makes
for
i
:=
range
tmperr
{
// the lifetime of tmperr clear...
tmperr
[
i
]
=
pi
[
i
]
-
math
.
Pi
// for garbage collector
}
pAbs
,
err
=
oneplot
(
tmperr
)
if
err
!=
nil
{
return
err
}
}
pAbs
.
X
.
Label
.
Text
=
step
pAbs
.
Y
.
Label
.
Text
=
"error"
dt
:=
draw
.
Tiles
{
Rows
:
3
,
Cols
:
1
,
PadTop
:
2
}
img
:=
vgimg
.
New
(
vg
.
Points
(
600
),
vg
.
Points
(
500
))
dc
:=
draw
.
New
(
img
)
dCnvs
:=
plot
.
Align
([][]
*
plot
.
Plot
{{
pPi
},
{
pStd
},
{
pAbs
}},
dt
,
dc
)
pPi
.
Draw
(
dCnvs
[
0
][
0
])
pStd
.
Draw
(
dCnvs
[
1
][
0
])
pAbs
.
Draw
(
dCnvs
[
2
][
0
])
w
,
err
:=
os
.
Create
(
plotName
)
if
err
!=
nil
{
return
fmt
.
Errorf
(
"Opening plotfile for writing %w"
,
err
)
}
defer
w
.
Close
()
breaker
(
"before vgimg"
)
jpg
:=
vgimg
.
JpegCanvas
{
Canvas
:
img
}
if
_
,
err
:=
jpg
.
WriteTo
(
w
);
err
!=
nil
{
return
err
}
pStd
.
Save
(
vg
.
Points
(
150
),
vg
.
Points
(
250
),
"foo.png"
)
return
nil
}
type
cmdArgs
struct
{
...
...
@@ -178,8 +89,8 @@ type cmdArgs struct {
func
cmdline
(
cmdArgs
*
cmdArgs
)
error
{
var
err
error
var
suppress
bool
flag
.
StringVar
(
&
cmdArgs
.
plotName
,
"p"
,
""
,
"
Plot
filename"
)
flag
.
BoolVar
(
&
suppress
,
"s"
,
false
,
"Suppress stdout"
)
flag
.
StringVar
(
&
cmdArgs
.
plotName
,
"p"
,
""
,
"filenam
e to Plot to. No name means no plofil
e"
)
flag
.
BoolVar
(
&
suppress
,
"s"
,
false
,
"Suppress stdout
- the long table of numbers
"
)
flag
.
Parse
()
if
flag
.
NArg
()
!=
3
{
return
errors
.
New
(
"Wrong number of command line args"
)
...
...
@@ -201,7 +112,6 @@ func cmdline(cmdArgs *cmdArgs) error {
return
nil
}
// main. The rules say ./pi seed nsteps nstep_print
func
main
()
{
var
cmdArgs
cmdArgs
if
err
:=
cmdline
(
&
cmdArgs
);
err
!=
nil
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment