Skip to content

Commit 357b22f

Browse files
Merge pull request #64 from MatthewSZhang/narx-mulit-doc
DOC add multi-output narx example
2 parents e6ed426 + 32b9809 commit 357b22f

File tree

3 files changed

+6211
-1282
lines changed

3 files changed

+6211
-1282
lines changed

examples/plot_narx_multi.py

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
"""
2+
=======================
3+
Mulit-output NARX model
4+
=======================
5+
6+
.. currentmodule:: fastcan
7+
8+
In this example, we illustrate how to build a multi-output polynomial
9+
NARX model for time series prediction.
10+
"""
11+
12+
# Authors: The fastcan developers
13+
# SPDX-License-Identifier: MIT
14+
15+
# %%
16+
# Prepare data
17+
# ------------
18+
#
19+
# First, a simulated time series dataset is generated from the following nonlinear
20+
# system.
21+
#
22+
# .. math::
23+
# y_0(k) &=\\
24+
# &0.5y_0(k-1) + 0.8y_1(k-1) + 0.3u_0(k)^2 + 2u_0(k-1)u_0(k-3) +
25+
# 1.5u_0(k-2)u_1(k-3) + 1\\
26+
# y_1(k) &=\\
27+
# &0.6y_1(k-1) - 0.2y_0(k-1)y_1(k-2) + 0.3u_1(k)^2 + 1.5u_1(k-2)u_0(k-3)
28+
# + 0.5
29+
#
30+
#
31+
# where :math:`k` is the time index,
32+
# :math:`u_0` and :math:`u_1` are input signals,
33+
# and :math:`y_0` and :math:`y_1` are output signals.
34+
35+
import numpy as np
36+
37+
rng = np.random.default_rng(12345)
38+
n_samples = 1000
39+
max_delay = 3
40+
e0 = rng.normal(0, 0.1, n_samples)
41+
e1 = rng.normal(0, 0.02, n_samples)
42+
u0 = rng.uniform(0, 1, n_samples + max_delay)
43+
u1 = rng.normal(0, 0.1, n_samples + max_delay)
44+
y0 = np.zeros(n_samples + max_delay)
45+
y1 = np.zeros(n_samples + max_delay)
46+
for i in range(max_delay, n_samples + max_delay):
47+
y0[i] = (
48+
0.5 * y0[i - 1]
49+
+ 0.8 * y1[i - 1]
50+
+ 0.3 * u0[i] ** 2
51+
+ 2 * u0[i - 1] * u0[i - 3]
52+
+ 1.5 * u0[i - 2] * u1[i - 3]
53+
+ 1
54+
)
55+
y1[i] = (
56+
0.6 * y1[i - 1]
57+
- 0.2 * y0[i - 1] * y1[i - 2]
58+
+ 0.3 * u1[i] ** 2
59+
+ 1.5 * u1[i - 2] * u0[i - 3]
60+
+ 0.5
61+
)
62+
y = np.c_[y0[max_delay:] + e0, y1[max_delay:] + e1]
63+
X = np.c_[u0[max_delay:], u1[max_delay:]]
64+
65+
66+
# %%
67+
# Identify the mulit-output NARX model
68+
# ------------------------------------
69+
# We provide :meth:`narx.make_narx` to automatically find the model
70+
# structure. `n_terms_to_select` can be a list to indicate the number
71+
# of terms (excluding intercept) for each output.
72+
73+
from fastcan.narx import make_narx, print_narx
74+
75+
narx_model = make_narx(
76+
X=X,
77+
y=y,
78+
n_terms_to_select=[5, 4],
79+
max_delay=3,
80+
poly_degree=2,
81+
verbose=0,
82+
).fit(X, y)
83+
84+
print_narx(narx_model, term_space=30)
85+
86+
87+
# %%
88+
# Plot NARX prediction performance
89+
# --------------------------------
90+
91+
import matplotlib.pyplot as plt
92+
from sklearn.metrics import r2_score
93+
94+
y_pred = narx_model.predict(
95+
X[:100],
96+
y_init=y[: narx_model.max_delay_], # Set the initial values of the prediction to
97+
# the true values
98+
)
99+
100+
plt.plot(y[:100], label="True")
101+
plt.plot(y_pred, label="Predicted")
102+
plt.xlabel("Time index k")
103+
plt.legend(["y0 True", "y1 True", "y0 Pred", "y1 Pred"], loc="right")
104+
plt.title(f"NARX prediction R-squared: {r2_score(y[:100], y_pred):.5f}")
105+
plt.show()

0 commit comments

Comments
 (0)