-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathPolynomialRegression.jl
93 lines (81 loc) · 2.35 KB
/
PolynomialRegression.jl
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
"""
multi_index(n::Int, k::Int)
Calculate an `Int` matrix as `Vector{Vector{Int}}` of size (m,n) where each row
represents an n-dimensional multi-index α with degree |α| < k.
"""
function multi_index(n::Int, k::Int)
if n == 1
return [ [i] for i in 0:k-1 ]
end
vec = Vector{Vector{Int}}[]
for i in 0:k-1
for s in multi_index(n-1, k-i)
elm = vcat(s, [i])
vec = vcat(vec, [elm])
end
end
return vec
end
"""
monomials(C::AbstractMatrix, V::AbstractMatrix)
Calculate monomials M of size (m,p) for a matrix of controls C of
size (n,p) and a matrix V of multi-indices α. V is of size (m,n).
"""
function monomials(C::AbstractMatrix, V::AbstractMatrix)
row(i) = begin
m = ones(size(C)[2])
for j in 1:size(V)[2]
m = m .* (C[j,:].^V[i,j])
end
return reshape(m, (1,:))
end
M = vcat([ row(i) for i in 1:size(V)[1] ]...)
return M
end
"""
struct PolynomialRegression
V::Matrix{Int}
beta::AbstractVector
end
A `PolynomialRegression` holds allows to predict values of a multi-variate
function. The polynomial degrees are encoded in the multi-index matrix *V*.
The polynomial coefficients are stored in the vector *beta*.
"""
struct PolynomialRegression
V::Matrix{Int}
beta::AbstractVector
end
"""
polynomial_regression(
C::AbstractMatrix,
O::AbstractVector,
max_degree::Int,
)
Calibrate a `PolynomialRegression` object from a matrix of controls C of
size (n,p) and a vector of observations O of size (p,). The maximum
polynomial degree is given by max_degree.
"""
function polynomial_regression(
C::AbstractMatrix,
O::AbstractVector,
max_degree::Int,
)
@assert size(C)[1] > 0
@assert size(C)[2] == length(O)
V = multi_index(size(C)[1], max_degree + 1)
V = Matrix(reduce(hcat, V)')
M = monomials(C, V)
@assert size(M)[2] == length(O)
beta = M' \ O # Solve via linear least squares.
return PolynomialRegression(V, beta)
end
"""
predict(reg::PolynomialRegression, C::AbstractMatrix)
Use a calibrated polynomial regression to predict function values.
Input is a matrix of controls C of size (n,p). Result is a vector
of size (p,).
"""
function predict(reg::PolynomialRegression, C::AbstractMatrix)
M = monomials(C, reg.V)
return M' * reg.beta
end