|
1 | 1 | using Symbolics, Test |
2 | 2 | using ReferenceTests |
3 | 3 |
|
| 4 | +# The ordering of operands within commutative `+` and `*` in the generated code |
| 5 | +# follows SymbolicUtils' argument sorting, which is benign but has changed across |
| 6 | +# versions (e.g. `a * b` vs `b * a`). To keep these tests stable across the CI |
| 7 | +# Julia/SymbolicUtils matrix we compare structure modulo that ordering rather than |
| 8 | +# byte-for-byte against a reference file. This mirrors the scalar Stan/MATLAB |
| 9 | +# tests further down, which were already converted for the same reason. |
| 10 | +function normalize_terms(rhs) |
| 11 | + summands = map(strip, split(rhs, " + ")) |
| 12 | + canonical = map(summands) do summand |
| 13 | + join(sort(map(strip, split(summand, " * "))), " * ") |
| 14 | + end |
| 15 | + return sort(canonical) |
| 16 | +end |
| 17 | + |
4 | 18 | @variables t a x(t) y(t) |
5 | 19 | expr = [a*x - x*y,-3y + x*y] |
6 | | -@test_reference "target_functions/1.stan" Symbolics.build_function(expr,[x,y],[a],t,target = Symbolics.StanTarget()) |
7 | 20 |
|
8 | | -@test_reference "target_functions/1.c" Symbolics.build_function(expr,[x,y],[a],t,target = Symbolics.CTarget(), |
| 21 | +# StanTarget structural test (was target_functions/1.stan) |
| 22 | +let |
| 23 | + sfunc = Symbolics.build_function(expr,[x,y],[a],t,target = Symbolics.StanTarget()) |
| 24 | + @test occursin("vector diffeqf(real t,vector internal_var___u,vector internal_var___p)", sfunc) |
| 25 | + @test occursin("vector[2] internal_var___du;", sfunc) |
| 26 | + @test occursin("return internal_var___du;", sfunc) |
| 27 | + m1 = match(r"internal_var___du\[1\] = (.+);", sfunc) |
| 28 | + m2 = match(r"internal_var___du\[2\] = (.+);", sfunc) |
| 29 | + @test m1 !== nothing && m2 !== nothing |
| 30 | + @test normalize_terms(m1[1]) == |
| 31 | + normalize_terms("internal_var___p[1] * internal_var___u[1] + -1 * internal_var___u[1] * internal_var___u[2]") |
| 32 | + @test normalize_terms(m2[1]) == |
| 33 | + normalize_terms("-3 * internal_var___u[2] + internal_var___u[1] * internal_var___u[2]") |
| 34 | +end |
| 35 | + |
| 36 | +# CTarget structural test (was target_functions/1.c) |
| 37 | +let |
| 38 | + cfunc = Symbolics.build_function(expr,[x,y],[a],t,target = Symbolics.CTarget(), |
9 | 39 | lhsname=:internal_var___du, |
10 | 40 | rhsnames=[:internal_var___u,:internal_var___p,:t]) |
| 41 | + @test occursin("#include <math.h>", cfunc) |
| 42 | + @test occursin("void diffeqf(double* internal_var___du, const double* internal_var___u, const double* internal_var___p, const double t)", cfunc) |
| 43 | + m1 = match(r"internal_var___du\[0\] = (.+);", cfunc) |
| 44 | + m2 = match(r"internal_var___du\[1\] = (.+);", cfunc) |
| 45 | + @test m1 !== nothing && m2 !== nothing |
| 46 | + @test normalize_terms(m1[1]) == |
| 47 | + normalize_terms("internal_var___p[0] * internal_var___u[0] + -1 * internal_var___u[0] * internal_var___u[1]") |
| 48 | + @test normalize_terms(m2[1]) == |
| 49 | + normalize_terms("-3 * internal_var___u[1] + internal_var___u[0] * internal_var___u[1]") |
| 50 | +end |
11 | 51 |
|
12 | | -@test_reference "target_functions/1.m" Symbolics.build_function(expr,[x,y],[a],t,target = Symbolics.MATLABTarget()) |
| 52 | +# MATLABTarget structural test (was target_functions/1.m) |
| 53 | +let |
| 54 | + mfunc = Symbolics.build_function(expr,[x,y],[a],t,target = Symbolics.MATLABTarget()) |
| 55 | + @test occursin("diffeqf = @(internal_var___t,internal_var___u)", mfunc) |
| 56 | + rows = [m[1] for m in eachmatch(r"([^\[\];\n]+);", mfunc)] |
| 57 | + @test length(rows) == 2 |
| 58 | + @test normalize_terms(rows[1]) == |
| 59 | + normalize_terms("internal_var___p(1) * internal_var___u(1) + -1 * internal_var___u(1) * internal_var___u(2)") |
| 60 | + @test normalize_terms(rows[2]) == |
| 61 | + normalize_terms("-3 * internal_var___u(2) + internal_var___u(1) * internal_var___u(2)") |
| 62 | +end |
13 | 63 |
|
14 | 64 | @test Symbolics.build_function(expr,[x,y],[a],t,target = Symbolics.CTarget(), |
15 | 65 | lhsname=:internal_var___du, |
|
0 commit comments