Skip to content

Commit cb6a3b1

Browse files
FIX ensure y_init is C-contiguous (#164)
1 parent 9fbfb90 commit cb6a3b1

File tree

2 files changed

+64
-55
lines changed

2 files changed

+64
-55
lines changed

fastcan/narx/_base.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def fit(self, X, y, sample_weight=None, coef_init=None, **params):
205205
"""
206206
none_inputs = False
207207
if X is None: # Auto-regressive model
208-
X = np.empty((1, 0), dtype=float) # Skip validation
208+
X = np.empty((1, 0), dtype=float, order="C") # Skip validation
209209
none_inputs = True
210210
check_X_params = dict(
211211
dtype=float, order="C", ensure_all_finite="allow-nan", ensure_min_features=0
@@ -572,6 +572,7 @@ def predict(self, X, y_init=None):
572572
y_init,
573573
ensure_2d=False,
574574
dtype=float,
575+
order="C",
575576
ensure_min_samples=0,
576577
ensure_all_finite="allow-nan",
577578
)

fastcan/narx/tests/test_narx.py

Lines changed: 62 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -43,60 +43,68 @@ def test_time_ids():
4343
@pytest.mark.parametrize("nan", [False, True])
4444
def test_narx(nan, multi_output):
4545
"""Test NARX"""
46-
if multi_output:
47-
rng = np.random.default_rng(12345)
48-
n_samples = 1000
49-
max_delay = 3
50-
e0 = rng.normal(0, 0.1, n_samples)
51-
e1 = rng.normal(0, 0.02, n_samples)
52-
u0 = rng.uniform(0, 1, n_samples + max_delay)
53-
u1 = rng.normal(0, 0.1, n_samples + max_delay)
54-
y0 = np.zeros(n_samples + max_delay)
55-
y1 = np.zeros(n_samples + max_delay)
56-
for i in range(max_delay, n_samples + max_delay):
57-
y0[i] = (
58-
0.5 * y0[i - 1]
59-
+ 0.8 * y1[i - 1]
60-
+ 0.3 * u0[i] ** 2
61-
+ 2 * u0[i - 1] * u0[i - 3]
62-
+ 1.5 * u0[i - 2] * u1[i - 3]
63-
+ 1
64-
)
65-
y1[i] = (
66-
0.6 * y1[i - 1]
67-
- 0.2 * y0[i - 1] * y1[i - 2]
68-
+ 0.3 * u1[i] ** 2
69-
+ 1.5 * u1[i - 2] * u0[i - 3]
70-
+ 0.5
71-
)
72-
y = np.c_[y0[max_delay:] + e0, y1[max_delay:] + e1]
73-
X = np.c_[u0[max_delay:], u1[max_delay:]]
74-
n_outputs = 2
75-
else:
76-
rng = np.random.default_rng(12345)
77-
n_samples = 1000
78-
max_delay = 3
79-
e = rng.normal(0, 0.1, n_samples)
80-
u0 = rng.uniform(0, 1, n_samples + max_delay)
81-
u1 = rng.normal(0, 0.1, n_samples)
82-
y = np.zeros(n_samples + max_delay)
83-
for i in range(max_delay, n_samples + max_delay):
84-
y[i] = (
85-
0.5 * y[i - 1]
86-
+ 0.3 * u0[i] ** 2
87-
+ 2 * u0[i - 1] * u0[i - 3]
88-
+ 1.5 * u0[i - 2] * u1[i - max_delay]
89-
+ 1
90-
)
91-
y = y[max_delay:] + e
92-
X = np.c_[u0[max_delay:], u1]
93-
n_outputs = 1
9446

95-
if nan:
96-
X_nan_ids = rng.choice(n_samples, 20, replace=False)
97-
y_nan_ids = rng.choice(n_samples, 10, replace=False)
98-
X[X_nan_ids] = np.nan
99-
y[y_nan_ids] = np.nan
47+
def make_data(multi_output, nan, rng):
48+
if multi_output:
49+
n_samples = 1000
50+
max_delay = 3
51+
e0 = rng.normal(0, 0.1, n_samples)
52+
e1 = rng.normal(0, 0.02, n_samples)
53+
u0 = rng.uniform(0, 1, n_samples + max_delay)
54+
u1 = rng.normal(0, 0.1, n_samples + max_delay)
55+
y0 = np.zeros(n_samples + max_delay)
56+
y1 = np.zeros(n_samples + max_delay)
57+
for i in range(max_delay, n_samples + max_delay):
58+
y0[i] = (
59+
0.5 * y0[i - 1]
60+
+ 0.8 * y1[i - 1]
61+
+ 0.3 * u0[i] ** 2
62+
+ 2 * u0[i - 1] * u0[i - 3]
63+
+ 1.5 * u0[i - 2] * u1[i - 3]
64+
+ 1
65+
)
66+
y1[i] = (
67+
0.6 * y1[i - 1]
68+
- 0.2 * y0[i - 1] * y1[i - 2]
69+
+ 0.3 * u1[i] ** 2
70+
+ 1.5 * u1[i - 2] * u0[i - 3]
71+
+ 0.5
72+
)
73+
y = np.c_[y0[max_delay:] + e0, y1[max_delay:] + e1]
74+
X = np.c_[u0[max_delay:], u1[max_delay:]]
75+
n_outputs = 2
76+
else:
77+
rng = np.random.default_rng(12345)
78+
n_samples = 1000
79+
max_delay = 3
80+
e = rng.normal(0, 0.1, n_samples)
81+
u0 = rng.uniform(0, 1, n_samples + max_delay)
82+
u1 = rng.normal(0, 0.1, n_samples)
83+
y = np.zeros(n_samples + max_delay)
84+
for i in range(max_delay, n_samples + max_delay):
85+
y[i] = (
86+
0.5 * y[i - 1]
87+
+ 0.3 * u0[i] ** 2
88+
+ 2 * u0[i - 1] * u0[i - 3]
89+
+ 1.5 * u0[i - 2] * u1[i - max_delay]
90+
+ 1
91+
)
92+
y = y[max_delay:] + e
93+
X = np.c_[u0[max_delay:], u1]
94+
n_outputs = 1
95+
96+
if nan:
97+
X_nan_ids = rng.choice(n_samples, 20, replace=False)
98+
y_nan_ids = rng.choice(n_samples, 10, replace=False)
99+
X[X_nan_ids] = np.nan
100+
y[y_nan_ids] = np.nan
101+
102+
X = np.asfortranarray(X)
103+
y = np.asfortranarray(y)
104+
return X, y, n_outputs
105+
106+
rng = np.random.default_rng(12345)
107+
X, y, n_outputs = make_data(multi_output, nan, rng)
100108

101109
if multi_output:
102110
narx_score = make_narx(
@@ -178,7 +186,7 @@ def test_narx(nan, multi_output):
178186
assert np.any(narx_osa_msa_coef != narx_array_init_msa.coef_)
179187

180188
if multi_output:
181-
y_init = np.ones((narx_array_init_msa.max_delay_, n_outputs))
189+
y_init = np.ones((narx_array_init_msa.max_delay_, n_outputs), order="F")
182190
else:
183191
y_init = [1] * narx_array_init_msa.max_delay_
184192
y_hat = narx_array_init_msa.predict(X, y_init=y_init)

0 commit comments

Comments
 (0)