|
1 | | -using SymbolicRegression |
| 1 | +@testitem "Early stop condition" tags = [:part2] begin |
| 2 | + using SymbolicRegression |
2 | 3 |
|
3 | | -X = randn(Float32, 5, 100) |
4 | | -y = 2 * cos.(X[4, :]) + X[1, :] .^ 2 |
| 4 | + X = randn(Float32, 5, 100) |
| 5 | + y = 2 * cos.(X[4, :]) + X[1, :] .^ 2 |
5 | 6 |
|
6 | | -early_stop(loss, c) = ((loss <= 1e-10) && (c <= 10)) |
| 7 | + early_stop(loss, c) = ((loss <= 1e-10) && (c <= 10)) |
7 | 8 |
|
8 | | -options = SymbolicRegression.Options(; |
9 | | - binary_operators=(+, *, /, -), |
10 | | - unary_operators=(cos, exp), |
11 | | - populations=20, |
12 | | - early_stop_condition=early_stop, |
13 | | -) |
| 9 | + options = SymbolicRegression.Options(; |
| 10 | + binary_operators=(+, *, /, -), |
| 11 | + unary_operators=(cos, exp), |
| 12 | + populations=20, |
| 13 | + early_stop_condition=early_stop, |
| 14 | + ) |
14 | 15 |
|
15 | | -hof = equation_search(X, y; options=options, niterations=1_000_000_000) |
| 16 | + hof = equation_search(X, y; options=options, niterations=1_000_000_000) |
16 | 17 |
|
17 | | -@test any( |
18 | | - early_stop(member.loss, count_nodes(member.tree)) for member in hof.members[hof.exists] |
19 | | -) |
| 18 | + @test any( |
| 19 | + early_stop(member.loss, count_nodes(member.tree)) for |
| 20 | + member in hof.members[hof.exists] |
| 21 | + ) |
| 22 | +end |
| 23 | + |
| 24 | +@testitem "State preservation with niterations=0" tags = [:part2] begin |
| 25 | + using SymbolicRegression |
| 26 | + using Random |
| 27 | + |
| 28 | + # Regression test for https://github.com/MilesCranmer/SymbolicRegression.jl/issues/178 |
| 29 | + |
| 30 | + rng = MersenneTwister(42) |
| 31 | + X = randn(rng, 2, 10) |
| 32 | + y = X[1, :] .+ X[2, :] |
| 33 | + |
| 34 | + options = Options(; |
| 35 | + binary_operators=(+,), |
| 36 | + unary_operators=(), |
| 37 | + verbosity=0, |
| 38 | + progress=false, |
| 39 | + population_size=5, |
| 40 | + populations=2, |
| 41 | + maxsize=5, |
| 42 | + tournament_selection_n=2, |
| 43 | + ) |
| 44 | + |
| 45 | + # Manually create saved state |
| 46 | + dataset = Dataset(X, y) |
| 47 | + pop1 = Population(dataset; population_size=5, nlength=3, options=options, nfeatures=2) |
| 48 | + pop2 = Population(dataset; population_size=5, nlength=3, options=options, nfeatures=2) |
| 49 | + hof = HallOfFame(options, dataset) |
| 50 | + |
| 51 | + saved_pops = [[pop1, pop2]] |
| 52 | + saved_hof = [hof] |
| 53 | + saved_state = (saved_pops, saved_hof) |
| 54 | + |
| 55 | + # Run with niterations=0 - should preserve populations |
| 56 | + result_pops, result_hof = equation_search( |
| 57 | + X, |
| 58 | + y; |
| 59 | + niterations=0, |
| 60 | + saved_state=saved_state, |
| 61 | + options=options, |
| 62 | + parallelism=:serial, |
| 63 | + return_state=true, |
| 64 | + ) |
| 65 | + |
| 66 | + # Verify populations are preserved (not reset to size 1) |
| 67 | + @test length(result_pops[1]) == 2 |
| 68 | + @test all(pop -> length(pop.members) == 5, result_pops[1]) |
| 69 | +end |
0 commit comments