-
Notifications
You must be signed in to change notification settings - Fork 0
/
common.go
75 lines (67 loc) · 2.85 KB
/
common.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
69
70
71
72
73
74
75
// Core data type definitions.
//
// Copyright (C) 2020 Juan Marín Noguera
//
// This file is part of Solvned.
//
// Solvned is free software: you can redistribute it and/or modify it under the
// terms of the GNU Lesser General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option) any
// later version.
//
// Solvned is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
// A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
// details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with Solvned. If not, see <https://www.gnu.org/licenses/>.
package mned
/*
This package implements several methods to compute approximations of
solutions of initial value problems (IVPs) with first-order ODEs. These problems
have the form
```
x'(t) = f(t, x(t)),
x(t0) = x0,
```
where `t0 : R` and `x0 : R^n` are the **initial values**,
`f : Ω ⊆ R x R^n -> R^n` is the **derivative function**, and `x : I ⊆ R -> R^n`
is the unknown of the equation. Here `I` is an open interval of `R` containing
`t0` and `Ω` is an open subset of `R x R^n` containing `(t0, x0)`.
We refer to `t` as the **independent variable** and to `x(t)` as the `dependent
variable`. We know that `x` is uniquely defined in a neighbourhood of `t0`.
Given a point `t` in such a neighbourhood, we say that `(t,x(t))` is a point of
the solution of the initial value problem.
The results calculated will be approximations, and judgement is required to get
approximations suitable for a particular problem; nevertheless, for the purpose
of explanation, we will use the same terminology for the approximations than for
the actual functions.
*/
// A Point is an element of the solution, given by the values of the independent
// and dependent variables.
type Point struct {
Time float64 // The independent variable.
Value []float64 // The dependent variable.
}
// Deep-copy a point.
func (p *Point) Clone() Point {
value := make([]float64, len(p.Value))
copy(value, p.Value)
return Point{Time: p.Time, Value: value}
}
// An IVP is an initial value problem given by a first-order ODE. It's given by
// the Derivative function, which is a pure function, and the initial values.
//
// The second return value of Derivative indicates if the Point was in the
// domain of the function. If it wasn't the first return value should not be
// used. Ideally, the domain should be restricted to the connected component of
// the initial value, as otherwise a solving method could "jump" to another
// component and the results from there on would be invalid.
type IVP struct {
Derivative func(Point) ([]float64, bool)
Start Point
}
func (ivp *IVP) Clone() IVP {
return IVP{Derivative: ivp.Derivative, Start: ivp.Start.Clone()}
}