-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrecdiff.t
70 lines (65 loc) · 2.1 KB
/
recdiff.t
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
-- SPDX-FileCopyrightText: 2024 René Hiemstra <[email protected]>
-- SPDX-FileCopyrightText: 2024 Torsten Keßler <[email protected]>
--
-- SPDX-License-Identifier: MIT
local concepts = require("concepts")
local sarray = require("sarray")
local darray = require("darray")
local qr = require("qr")
local range = require("range")
import "terraform"
local concept RecDiff(T) where {T: concepts.Number}
local Integral = concepts.Integer
Self.traits.ninit = concepts.traittag
Self.traits.depth = concepts.traittag
Self.traits.eltype = T
local Stack = concepts.Stack(T)
terra Self:getcoeff(n: Integral, y: &Stack): {} end
terra Self:getinit(y0: &Stack): {} end
end
local Real = concepts.Real
local Vector = concepts.Vector
local terraform olver(alloc, rec: &R, yn: &V)
where {R: RecDiff(Real), V: Vector(Real)}
var y0 = [sarray.StaticVector(R.traits.eltype, R.traits.ninit)].zeros()
var nmax = yn:length()
var n0 = y0:length()
var dim: int64 = nmax - n0
var sys = [darray.DynamicMatrix(R.traits.eltype)].zeros(alloc, {dim, dim})
var rhs = [darray.DynamicVector(R.traits.eltype)].zeros(alloc, dim)
var hrf = [darray.DynamicVector(R.traits.eltype)].zeros(alloc, dim)
var y = [sarray.StaticVector(R.traits.eltype, R.traits.depth + 1)].zeros()
for i = 0, dim do
var n = n0 + i
rec:getcoeff(n, &y)
for offset = 0, [R.traits.depth] do
var j = i + offset - [R.traits.depth] / 2
if j >= 0 and j < dim then
sys(i, j) = y:get(offset)
end
end
rhs:set(i, y:get([R.traits.depth]))
end
rec:getinit(&y0)
for i = 0, n0 do
rec:getcoeff(n0 + i, &y)
var r = rhs:get(i)
for j = i, n0 do
r = r - y:get(j - i) * y0:get(j)
end
rhs:set(i, r)
end
var qr = [qr.QRFactory(sys.type, rhs.type)].new(&sys, &hrf)
qr:factorize()
qr:solve(false, &rhs)
for i = 0, n0 do
yn:set(i, y0:get(i))
end
for i = n0, nmax do
yn:set(i, rhs:get(i - n0))
end
end
return {
RecDiff = RecDiff,
olver = olver,
}