@@ -148,150 +148,152 @@ dependencies(row) = sort(rowvals(row) .=> nonzeros(row), by = first)
148
148
@test_throws " absence of state dependence for time" Incidence (Const (0.0 ), IncidenceValue[linear, linear_time_dependent])
149
149
end
150
150
151
- incidence = @infer_incidence t
152
- @test incidence. typ === Const (0.0 )
153
- @test dependencies (incidence. row) == [1 => 1 ]
154
- @test incidence == incidence " t"
155
-
156
- incidence = @infer_incidence 5. + ᵢ u₁
157
- @test incidence. typ === Const (5.0 )
158
- @test dependencies (incidence. row) == [2 => 1 ]
159
- @test incidence == incidence " 5.0 + u₁"
160
-
161
- incidence = @infer_incidence 5.0 + ᵢ t + ᵢ u₁
162
- @test incidence. typ === Const (5.0 )
163
- @test dependencies (incidence. row) == [1 => 1 , 2 => 1 ]
164
- @test incidence == incidence " 5.0 + t + u₁"
165
-
166
- incidence = @infer_incidence t * ᵢ u₁
167
- @test incidence. typ === Const (0.0 )
168
- @test dependencies (incidence. row) == [1 => linear_state_dependent, 2 => linear_time_dependent]
169
- @test incidence == incidence " f(∝ₛt, ∝ₜu₁)"
170
-
171
- incidence = @infer_incidence u₁
172
- @test incidence. typ === Const (0.0 )
173
- @test dependencies (incidence. row) == [2 => 1 ]
174
- @test incidence == incidence " u₁"
175
-
176
- incidence = @infer_incidence u₁ + ᵢ u₂
177
- @test incidence. typ === Const (0.0 )
178
- @test dependencies (incidence. row) == [2 => 1 , 3 => 1 ]
179
- @test incidence == incidence " u₁ + u₂"
180
-
181
- incidence = @infer_incidence u₁ * ᵢ u₂
182
- @test incidence. typ === Const (0.0 )
183
- @test dependencies (incidence. row) == [2 => linear_state_dependent, 3 => linear_state_dependent]
184
- @test incidence == incidence " f(∝ₛu₁, ∝ₛu₂)"
185
-
186
- incidence = @infer_incidence (2.0 + ᵢ u₁) * ᵢ (3.0 + ᵢ u₂)
187
- @test incidence. typ === Const (6.0 )
188
- @test dependencies (incidence. row) == [2 => linear_state_dependent, 3 => linear_state_dependent]
189
- @test incidence == incidence " 6.0 + f(∝ₛu₁, ∝ₛu₂)"
190
-
191
- incidence = @infer_incidence (2.0 + ᵢ u₁) * ᵢ (3.0 + ᵢ u₁ * ᵢ u₂)
192
- @test incidence. typ === Const (6.0 )
193
- @test dependencies (incidence. row) == [2 => nonlinear, 3 => linear_state_dependent]
194
- @test incidence == incidence " 6.0 + f(u₁, ∝ₛu₂)"
195
-
196
- incidence = @infer_incidence (2.0 + ᵢ u₁) * ᵢ (3.0 + ᵢ u₁ * ᵢ u₂) + ᵢ u₃
197
- @test incidence. typ === Const (6.0 )
198
- @test dependencies (incidence. row) == [2 => nonlinear, 3 => linear_state_dependent, 4 => 1.0 ]
199
- @test incidence == incidence " 6.0 + u₃ + f(u₁, ∝ₛu₂)"
200
-
201
- incidence = @infer_incidence (u₁ + ᵢ u₂) * ᵢ t
202
- @test incidence. typ === Const (0.0 )
203
- @test dependencies (incidence. row) == [1 => linear_state_dependent, (2 : 3 .=> linear_time_dependent). .. ]
204
- @test incidence == incidence " f(∝ₛt, ∝ₜu₁, ∝ₜu₂)"
205
-
206
- incidence = @infer_incidence u₁ * ᵢ u₂ + ᵢ (u₁ + ᵢ t) * ᵢ u₃
207
- @test dependencies (incidence. row) == [(1 : 3 .=> linear_state_dependent). .. , 4 => linear_time_and_state_dependent]
208
- @test incidence == incidence " f(∝ₛt, ∝ₛu₁, ∝ₛu₂, ∝ₜₛu₃)"
209
-
210
- # IPO
211
-
212
- # NOTE: Most of additive terms (`.typ`) can't be precise given the current IPO representation.
213
- # We expect `Const(0.0)` in most cases, but widen to `Float64`.
214
-
215
- incidence = @infer_incidence 1.0 t * 3.0
216
- @test dependencies (incidence. row) == [1 => linear]
217
- @test incidence == incidence " a + ∝t"
218
-
219
- incidence = @infer_incidence (1.0 + u₁ + ᵢ u₂) * 1.0
220
- @test incidence. typ === Float64
221
- @test dependencies (incidence. row) == (2 : 3 .=> linear_state_dependent)
222
- @test incidence == incidence " a + f(∝ₛu₁, ∝ₛu₂)"
223
-
224
- incidence = @infer_incidence (2.0 + u₁) * (3.0 + u₂)
225
- @test dependencies (incidence. row) == [2 => linear_state_dependent, 3 => linear_state_dependent]
226
- @test incidence == incidence " a + f(∝ₛu₁, ∝ₛu₂)"
227
-
228
- incidence = @infer_incidence 5.0 + u₁
229
- @test incidence. typ === Const (5.0 )
230
- @test dependencies (incidence. row) == [2 => 1 ]
231
- @test incidence == incidence " 5.0 + u₁"
232
-
233
- incidence = @infer_incidence u₁ * u₁
234
- @test dependencies (incidence. row) == [2 => nonlinear]
235
- @test incidence == incidence " f(u₁)"
236
-
237
- incidence = @infer_incidence t * t
238
- @test dependencies (incidence. row) == [1 => nonlinear]
239
- @test incidence == incidence " f(t)"
240
-
241
- mul3 (a, b, c) = a * ᵢ (b * ᵢ c)
242
- incidence = @infer_incidence mul3 (t, u₁, u₂)
243
- @test dependencies (incidence. row) == [1 => linear_state_dependent, (2 : 3 .=> linear_time_and_state_dependent). .. ]
244
- @test incidence == incidence " f(∝ₛt, ∝ₜₛu₁, ∝ₜₛu₂)"
245
-
246
- incidence = @infer_incidence mul3 (t, u₁, u₁)
247
- @test dependencies (incidence. row) == [1 => linear_state_dependent, 2 => nonlinear]
248
- @test incidence == incidence " f(∝ₛt, u₁)"
249
-
250
- incidence = @infer_incidence mul3 (t, u₁, t)
251
- # If we knew which state is used for state dependence,
252
- # state should be inferred as linear_time_dependent.
253
- @test dependencies (incidence. row) == [1 => nonlinear, 2 => linear_time_and_state_dependent]
254
- @test incidence == incidence " f(t, ∝ₜₛu₁)"
255
-
256
- incidence = @infer_incidence mul3 (u₂, u₁, u₂)
257
- @test dependencies (incidence. row) == [2 => linear_state_dependent, 3 => nonlinear]
258
- @test incidence == incidence " f(∝ₛu₁, u₂)"
259
-
260
- _muladd (a, b, c) = a + ᵢ b * ᵢ c
261
- incidence = @infer_incidence _muladd (u₁, u₁, u₂)
262
- # We widen to `nonlinear` because we can't yet infer that `b := u₁` is
263
- # not multiplied by `a := u₁`. The solution would be to see that `a`
264
- # is linear but state-independent and therefore can't be a factor of `b`.
265
- @test dependencies (incidence. row) == [2 => nonlinear, 3 => linear_state_dependent]
266
- @test incidence == incidence " f(u₁, ∝ₛu₂)"
267
-
268
- # Here we still wouldn't be able to use the above solution because `a := u₁` is state-dependent.
269
- # So `c := u₁` having a state-dependent coefficient might be multiplied by `a` a.k.a itself
270
- # which would make it nonlinear, so IPO can only infer `u₁` as nonlinear.
271
- _muladd2 (a, b, c, d) = d * ᵢ a + ᵢ b * ᵢ c
272
- incidence = @infer_incidence _muladd2 (u₁, u₂, u₁, u₃)
273
- @test dependencies (incidence. row) == [2 => nonlinear, 3 => linear_state_dependent, 4 => linear_state_dependent]
274
- @test incidence == incidence " f(u₁, ∝ₛu₂, ∝ₛu₃)"
275
-
276
- incidence = @infer_incidence exp (u₁)
277
- @test dependencies (incidence. row) == [2 => nonlinear]
278
- @test incidence == incidence " a + f(u₁)"
279
-
280
- incidence = @infer_incidence t * exp (u₁)
281
- @test dependencies (incidence. row) == [1 => linear_state_dependent, 2 => nonlinear]
282
- @test incidence == incidence " a + f(∝ₛt, u₁)"
283
-
284
- incidence = @infer_incidence u₁ * exp (t)
285
- @test dependencies (incidence. row) == [1 => nonlinear, 2 => linear_time_dependent]
286
- @test incidence == incidence " a + f(t, ∝ₜu₁)"
287
-
288
- incidence = @infer_incidence u₁ * exp (t + u₂)
289
- @test dependencies (incidence. row) == [1 => nonlinear, 2 => linear_time_and_state_dependent, 3 => nonlinear]
290
- @test incidence == incidence " a + f(t, ∝ₜₛu₁, u₂)"
291
-
292
- incidence = @infer_incidence atan (u₁, u₂)
293
- @test dependencies (incidence. row) == [2 => nonlinear, 3 => nonlinear]
294
- @test incidence == incidence " a + f(u₁, u₂)"
151
+ @testset " Basic lattice operations with intrinsic tfuncs" begin
152
+ incidence = @infer_incidence t
153
+ @test incidence. typ === Const (0.0 )
154
+ @test dependencies (incidence. row) == [1 => 1 ]
155
+ @test incidence == incidence " t"
156
+
157
+ incidence = @infer_incidence 5. + ᵢ u₁
158
+ @test incidence. typ === Const (5.0 )
159
+ @test dependencies (incidence. row) == [2 => 1 ]
160
+ @test incidence == incidence " 5.0 + u₁"
161
+
162
+ incidence = @infer_incidence 5.0 + ᵢ t + ᵢ u₁
163
+ @test incidence. typ === Const (5.0 )
164
+ @test dependencies (incidence. row) == [1 => 1 , 2 => 1 ]
165
+ @test incidence == incidence " 5.0 + t + u₁"
166
+
167
+ incidence = @infer_incidence t * ᵢ u₁
168
+ @test incidence. typ === Const (0.0 )
169
+ @test dependencies (incidence. row) == [1 => linear_state_dependent, 2 => linear_time_dependent]
170
+ @test incidence == incidence " f(∝ₛt, ∝ₜu₁)"
171
+
172
+ incidence = @infer_incidence u₁
173
+ @test incidence. typ === Const (0.0 )
174
+ @test dependencies (incidence. row) == [2 => 1 ]
175
+ @test incidence == incidence " u₁"
176
+
177
+ incidence = @infer_incidence u₁ + ᵢ u₂
178
+ @test incidence. typ === Const (0.0 )
179
+ @test dependencies (incidence. row) == [2 => 1 , 3 => 1 ]
180
+ @test incidence == incidence " u₁ + u₂"
181
+
182
+ incidence = @infer_incidence u₁ * ᵢ u₂
183
+ @test incidence. typ === Const (0.0 )
184
+ @test dependencies (incidence. row) == [2 => linear_state_dependent, 3 => linear_state_dependent]
185
+ @test incidence == incidence " f(∝ₛu₁, ∝ₛu₂)"
186
+
187
+ incidence = @infer_incidence (2.0 + ᵢ u₁) * ᵢ (3.0 + ᵢ u₂)
188
+ @test incidence. typ === Const (6.0 )
189
+ @test dependencies (incidence. row) == [2 => linear_state_dependent, 3 => linear_state_dependent]
190
+ @test incidence == incidence " 6.0 + f(∝ₛu₁, ∝ₛu₂)"
191
+
192
+ incidence = @infer_incidence (2.0 + ᵢ u₁) * ᵢ (3.0 + ᵢ u₁ * ᵢ u₂)
193
+ @test incidence. typ === Const (6.0 )
194
+ @test dependencies (incidence. row) == [2 => nonlinear, 3 => linear_state_dependent]
195
+ @test incidence == incidence " 6.0 + f(u₁, ∝ₛu₂)"
196
+
197
+ incidence = @infer_incidence (2.0 + ᵢ u₁) * ᵢ (3.0 + ᵢ u₁ * ᵢ u₂) + ᵢ u₃
198
+ @test incidence. typ === Const (6.0 )
199
+ @test dependencies (incidence. row) == [2 => nonlinear, 3 => linear_state_dependent, 4 => 1.0 ]
200
+ @test incidence == incidence " 6.0 + u₃ + f(u₁, ∝ₛu₂)"
201
+
202
+ incidence = @infer_incidence (u₁ + ᵢ u₂) * ᵢ t
203
+ @test incidence. typ === Const (0.0 )
204
+ @test dependencies (incidence. row) == [1 => linear_state_dependent, (2 : 3 .=> linear_time_dependent). .. ]
205
+ @test incidence == incidence " f(∝ₛt, ∝ₜu₁, ∝ₜu₂)"
206
+
207
+ incidence = @infer_incidence u₁ * ᵢ u₂ + ᵢ (u₁ + ᵢ t) * ᵢ u₃
208
+ @test dependencies (incidence. row) == [(1 : 3 .=> linear_state_dependent). .. , 4 => linear_time_and_state_dependent]
209
+ @test incidence == incidence " f(∝ₛt, ∝ₛu₁, ∝ₛu₂, ∝ₜₛu₃)"
210
+ end
211
+
212
+ @testset " IPO" begin
213
+ # NOTE: Most of additive terms (`.typ`) can't be precise given the current IPO representation.
214
+ # We expect `Const(0.0)` in most cases, but widen to `Float64`.
215
+
216
+ incidence = @infer_incidence 1.0 t * 3.0
217
+ @test dependencies (incidence. row) == [1 => linear]
218
+ @test incidence == incidence " a + ∝t"
219
+
220
+ incidence = @infer_incidence (1.0 + u₁ + ᵢ u₂) * 1.0
221
+ @test incidence. typ === Float64
222
+ @test dependencies (incidence. row) == (2 : 3 .=> linear_state_dependent)
223
+ @test incidence == incidence " a + f(∝ₛu₁, ∝ₛu₂)"
224
+
225
+ incidence = @infer_incidence (2.0 + u₁) * (3.0 + u₂)
226
+ @test dependencies (incidence. row) == [2 => linear_state_dependent, 3 => linear_state_dependent]
227
+ @test incidence == incidence " a + f(∝ₛu₁, ∝ₛu₂)"
228
+
229
+ incidence = @infer_incidence 5.0 + u₁
230
+ @test incidence. typ === Const (5.0 )
231
+ @test dependencies (incidence. row) == [2 => 1 ]
232
+ @test incidence == incidence " 5.0 + u₁"
233
+
234
+ incidence = @infer_incidence u₁ * u₁
235
+ @test dependencies (incidence. row) == [2 => nonlinear]
236
+ @test incidence == incidence " f(u₁)"
237
+
238
+ incidence = @infer_incidence t * t
239
+ @test dependencies (incidence. row) == [1 => nonlinear]
240
+ @test incidence == incidence " f(t)"
241
+
242
+ mul3 (a, b, c) = a * ᵢ (b * ᵢ c)
243
+ incidence = @infer_incidence mul3 (t, u₁, u₂)
244
+ @test dependencies (incidence. row) == [1 => linear_state_dependent, (2 : 3 .=> linear_time_and_state_dependent). .. ]
245
+ @test incidence == incidence " f(∝ₛt, ∝ₜₛu₁, ∝ₜₛu₂)"
246
+
247
+ incidence = @infer_incidence mul3 (t, u₁, u₁)
248
+ @test dependencies (incidence. row) == [1 => linear_state_dependent, 2 => nonlinear]
249
+ @test incidence == incidence " f(∝ₛt, u₁)"
250
+
251
+ incidence = @infer_incidence mul3 (t, u₁, t)
252
+ # If we knew which state is used for state dependence,
253
+ # state should be inferred as linear_time_dependent.
254
+ @test dependencies (incidence. row) == [1 => nonlinear, 2 => linear_time_and_state_dependent]
255
+ @test incidence == incidence " f(t, ∝ₜₛu₁)"
256
+
257
+ incidence = @infer_incidence mul3 (u₂, u₁, u₂)
258
+ @test dependencies (incidence. row) == [2 => linear_state_dependent, 3 => nonlinear]
259
+ @test incidence == incidence " f(∝ₛu₁, u₂)"
260
+
261
+ _muladd (a, b, c) = a + ᵢ b * ᵢ c
262
+ incidence = @infer_incidence _muladd (u₁, u₁, u₂)
263
+ # We widen to `nonlinear` because we can't yet infer that `b := u₁` is
264
+ # not multiplied by `a := u₁`. The solution would be to see that `a`
265
+ # is linear but state-independent and therefore can't be a factor of `b`.
266
+ @test dependencies (incidence. row) == [2 => nonlinear, 3 => linear_state_dependent]
267
+ @test incidence == incidence " f(u₁, ∝ₛu₂)"
268
+
269
+ # Here we still wouldn't be able to use the above solution because `a := u₁` is state-dependent.
270
+ # So `c := u₁` having a state-dependent coefficient might be multiplied by `a` a.k.a itself
271
+ # which would make it nonlinear, so IPO can only infer `u₁` as nonlinear.
272
+ _muladd2 (a, b, c, d) = d * ᵢ a + ᵢ b * ᵢ c
273
+ incidence = @infer_incidence _muladd2 (u₁, u₂, u₁, u₃)
274
+ @test dependencies (incidence. row) == [2 => nonlinear, 3 => linear_state_dependent, 4 => linear_state_dependent]
275
+ @test incidence == incidence " f(u₁, ∝ₛu₂, ∝ₛu₃)"
276
+
277
+ incidence = @infer_incidence exp (u₁)
278
+ @test dependencies (incidence. row) == [2 => nonlinear]
279
+ @test incidence == incidence " a + f(u₁)"
280
+
281
+ incidence = @infer_incidence t * exp (u₁)
282
+ @test dependencies (incidence. row) == [1 => linear_state_dependent, 2 => nonlinear]
283
+ @test incidence == incidence " a + f(∝ₛt, u₁)"
284
+
285
+ incidence = @infer_incidence u₁ * exp (t)
286
+ @test dependencies (incidence. row) == [1 => nonlinear, 2 => linear_time_dependent]
287
+ @test incidence == incidence " a + f(t, ∝ₜu₁)"
288
+
289
+ incidence = @infer_incidence u₁ * exp (t + u₂)
290
+ @test dependencies (incidence. row) == [1 => nonlinear, 2 => linear_time_and_state_dependent, 3 => nonlinear]
291
+ @test incidence == incidence " a + f(t, ∝ₜₛu₁, u₂)"
292
+
293
+ incidence = @infer_incidence atan (u₁, u₂)
294
+ @test dependencies (incidence. row) == [2 => nonlinear, 3 => nonlinear]
295
+ @test incidence == incidence " a + f(u₁, u₂)"
296
+ end
295
297
end ;
296
298
297
299
end
0 commit comments