-
Notifications
You must be signed in to change notification settings - Fork 1
/
timespan.go
68 lines (56 loc) · 1.6 KB
/
timespan.go
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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package godesim
// Timespan represents an iterable vector of evenly spaced time points.
// Does not store state information on steps done.
type Timespan struct {
start float64
end float64
steps int
stepLength float64
}
// Len how many iterations expected for RK4
func (ts Timespan) Len() int {
return ts.steps
}
// Dt Obtains the step length of simulation
func (ts Timespan) Dt() float64 {
return ts.stepLength
}
// End returns greater limit of Timespan
func (ts Timespan) End() float64 {
return ts.end
}
// SetTimespan Set time domain (step domain) for simulation.
// Step size is given by:
// dt = (End - Start) / float64(Steps)
// since Steps is the amount of points to "solve".
func (ts *Timespan) SetTimespan(Start, End float64, Steps int) {
(*ts) = newTimespan(Start, End, Steps)
}
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
)
// newTimespan generates a timespan object for simulation.
// Steps must be minimum 1.
func newTimespan(Start, End float64, Steps int) Timespan {
if Start >= End {
throwf("Timespan: Start cannot be greater or equal to End. got %v >= %v", Start, End)
}
if Steps < 1 {
throwf("Timespan: Steps must be greater or equal to 1. got %v", Steps)
}
dt := (End - Start) / float64(Steps)
if dt <= 2*dlamchP {
warnf("warning: time step %e is smaller than eps*2", dt)
}
return Timespan{
start: Start,
end: End,
steps: Steps,
stepLength: dt,
}
}