@@ -226,6 +226,7 @@ relates to error (precision) across different tolerance settings.
226226- `name`: Name of the algorithm
227227- `error_estimate`: Error metric used (e.g., `:final`, `:l2`)
228228- `N`: Number of tolerance settings tested
229+ - `tags`: Symbolic tags for categorizing this algorithm (e.g., `[:rosenbrock, :stiff, :4th_order]`)
229230
230231# Example
231232```julia
@@ -248,6 +249,7 @@ mutable struct WorkPrecision
248249 name:: Any
249250 error_estimate:: Any
250251 N:: Int
252+ tags:: Vector{Symbol}
251253end
252254
253255"""
294296function WorkPrecision (
295297 prob, alg, abstols, reltols, dts = nothing ;
296298 name = nothing , appxsol = nothing , error_estimate = :final ,
297- numruns = 20 , seconds = 2 , reduction = default_reduction, kwargs...
299+ numruns = 20 , seconds = 2 , reduction = default_reduction,
300+ tags:: Vector{Symbol} = Symbol[], kwargs...
298301)
299302 N = length (abstols)
300303 errors = Vector {Dict{Symbol, Float64}} (undef, N)
@@ -417,15 +420,16 @@ function WorkPrecision(
417420 end
418421 return WorkPrecision (
419422 prob, abstols, reltols, _dicts_to_structarray (errors),
420- times, dts, stats, name, error_estimate, N
423+ times, dts, stats, name, error_estimate, N, tags
421424 )
422425end
423426
424427# Work precision information for a BVP
425428function WorkPrecision (
426429 prob:: AbstractBVProblem , alg, abstols, reltols, dts = nothing ;
427430 name = nothing , appxsol = nothing , error_estimate = :final ,
428- numruns = 20 , seconds = 2 , reduction = default_reduction, kwargs...
431+ numruns = 20 , seconds = 2 , reduction = default_reduction,
432+ tags:: Vector{Symbol} = Symbol[], kwargs...
429433)
430434 N = length (abstols)
431435 errors = Vector {Dict{Symbol, Float64}} (undef, N)
@@ -547,15 +551,15 @@ function WorkPrecision(
547551 end
548552 return WorkPrecision (
549553 prob, abstols, reltols, _dicts_to_structarray (errors),
550- times, dts, stats, name, error_estimate, N
554+ times, dts, stats, name, error_estimate, N, tags
551555 )
552556end
553557
554558# Work precision information for a nonlinear problem.
555559function WorkPrecision (
556560 prob:: NonlinearProblem , alg, abstols, reltols, dts = nothing ; name = nothing ,
557561 appxsol = nothing , error_estimate = :l2 , numruns = 20 , seconds = 2 ,
558- reduction = default_reduction, kwargs...
562+ reduction = default_reduction, tags :: Vector{Symbol} = Symbol[], kwargs...
559563)
560564 N = length (abstols)
561565 errors = Vector {Dict{Symbol, Float64}} (undef, N)
@@ -612,7 +616,7 @@ function WorkPrecision(
612616
613617 return WorkPrecision (
614618 prob, abstols, reltols, _dicts_to_structarray (errors),
615- times, dts, stats, name, error_estimate, N
619+ times, dts, stats, name, error_estimate, N, tags
616620 )
617621end
618622
@@ -636,11 +640,13 @@ function WorkPrecisionSet(
636640 _dts = get (setups[i], :dts , nothing )
637641 filtered_setup = filter (p -> p. first in DiffEqBase. allowedkeywords, setups[i])
638642
643+ _tags = get (setups[i], :tags , Symbol[])
639644 wps[i] = WorkPrecision (
640645 prob, setups[i][:alg ], _abstols, _reltols, _dts;
641646 appxsol = appxsol,
642647 error_estimate = error_estimate,
643- name = names[i], reduction = reduction, kwargs... , filtered_setup...
648+ name = names[i], reduction = reduction,
649+ tags = _tags, kwargs... , filtered_setup...
644650 )
645651 end
646652 return WorkPrecisionSet (
@@ -792,7 +798,8 @@ function WorkPrecisionSet(
792798 wps = [WorkPrecision (
793799 prob, _abstols[i], _reltols[i],
794800 _dicts_to_structarray (errors[i]),
795- times[:, i], _dts[i], stats, names[i], error_estimate, N
801+ times[:, i], _dts[i], stats, names[i], error_estimate, N,
802+ get (setups[i], :tags , Symbol[])
796803 )
797804 for i in 1 : N]
798805 return WorkPrecisionSet (
@@ -922,7 +929,8 @@ function WorkPrecisionSet(
922929 stats = nothing
923930 wps = [WorkPrecision (
924931 prob, _abstols[i], _reltols[i], errors[i], times[:, i],
925- _dts[i], stats, names[i], error_estimate, N
932+ _dts[i], stats, names[i], error_estimate, N,
933+ get (setups[i], :tags , Symbol[])
926934 )
927935 for i in 1 : N]
928936 return WorkPrecisionSet (
@@ -951,11 +959,13 @@ function WorkPrecisionSet(
951959 _dts = get (setups[i], :dts , nothing )
952960 filtered_setup = filter (p -> p. first in DiffEqBase. allowedkeywords, setups[i])
953961
962+ _tags = get (setups[i], :tags , Symbol[])
954963 wps[i] = WorkPrecision (
955964 prob, setups[i][:alg ], _abstols, _reltols, _dts;
956965 appxsol = appxsol,
957966 error_estimate = error_estimate,
958- name = names[i], reduction = reduction, kwargs... , filtered_setup...
967+ name = names[i], reduction = reduction,
968+ tags = _tags, kwargs... , filtered_setup...
959969 )
960970 end
961971 return WorkPrecisionSet (
@@ -1040,6 +1050,97 @@ function get_sample_errors(
10401050 end
10411051end
10421052
1053+ """
1054+ filter_by_tags(wp_set::WorkPrecisionSet, tags::Symbol...) -> WorkPrecisionSet
1055+
1056+ Return a new `WorkPrecisionSet` containing only entries whose tags include
1057+ ALL of the specified tags (AND logic).
1058+
1059+ # Example
1060+ ```julia
1061+ setups = [
1062+ Dict(:alg => Rosenbrock23(), :tags => [:rosenbrock, :2nd_order]),
1063+ Dict(:alg => Rodas5P(), :tags => [:rosenbrock, :5th_order]),
1064+ Dict(:alg => TRBDF2(), :tags => [:bdf, :2nd_order]),
1065+ ]
1066+ wp_set = WorkPrecisionSet(prob, abstols, reltols, setups)
1067+ rosenbrock_only = filter_by_tags(wp_set, :rosenbrock)
1068+ second_order_rosenbrock = filter_by_tags(wp_set, :rosenbrock, :2nd_order)
1069+ ```
1070+ """
1071+ function filter_by_tags (wp_set:: WorkPrecisionSet , tags:: Symbol... )
1072+ isempty (tags) && return wp_set
1073+ indices = findall (wp -> all (t -> t in wp. tags, tags), wp_set. wps)
1074+ _subset_wps (wp_set, indices)
1075+ end
1076+
1077+ """
1078+ exclude_by_tags(wp_set::WorkPrecisionSet, tags::Symbol...) -> WorkPrecisionSet
1079+
1080+ Return a new `WorkPrecisionSet` excluding entries that have ANY of the specified tags.
1081+
1082+ # Example
1083+ ```julia
1084+ no_reference = exclude_by_tags(wp_set, :reference)
1085+ ```
1086+ """
1087+ function exclude_by_tags (wp_set:: WorkPrecisionSet , tags:: Symbol... )
1088+ isempty (tags) && return wp_set
1089+ indices = findall (wp -> ! any (t -> t in wp. tags, tags), wp_set. wps)
1090+ _subset_wps (wp_set, indices)
1091+ end
1092+
1093+ """
1094+ get_tags(wp_set::WorkPrecisionSet) -> Vector{Vector{Symbol}}
1095+
1096+ Return the tags for each entry in the `WorkPrecisionSet`.
1097+ """
1098+ get_tags (wp_set:: WorkPrecisionSet ) = [wp. tags for wp in wp_set. wps]
1099+
1100+ """
1101+ unique_tags(wp_set::WorkPrecisionSet) -> Vector{Symbol}
1102+
1103+ Return all unique tags present across entries in the `WorkPrecisionSet`.
1104+ """
1105+ function unique_tags (wp_set:: WorkPrecisionSet )
1106+ alltags = Symbol[]
1107+ for wp in wp_set. wps
1108+ append! (alltags, wp. tags)
1109+ end
1110+ return unique! (sort! (alltags))
1111+ end
1112+
1113+ """
1114+ merge_wp_sets(sets::WorkPrecisionSet...) -> WorkPrecisionSet
1115+
1116+ Merge multiple `WorkPrecisionSet`s into a single set. All entries are combined.
1117+ The metadata (abstols, reltols, prob, error_estimate) is taken from the first set.
1118+ """
1119+ function merge_wp_sets (sets:: WorkPrecisionSet... )
1120+ isempty (sets) && throw (ArgumentError (" At least one WorkPrecisionSet is required" ))
1121+ wps = vcat ([s. wps for s in sets]. .. )
1122+ all_setups = vcat ([s. setups for s in sets]. .. )
1123+ all_names = vcat ([s. names for s in sets]. .. )
1124+ N = length (wps)
1125+ first_set = first (sets)
1126+ return WorkPrecisionSet (
1127+ wps, N, first_set. abstols, first_set. reltols, first_set. prob,
1128+ all_setups, all_names, first_set. error_estimate, first_set. numruns
1129+ )
1130+ end
1131+
1132+ function _subset_wps (wp_set:: WorkPrecisionSet , indices:: Vector{Int} )
1133+ isempty (indices) &&
1134+ @warn " No entries match the specified tags. Returning empty WorkPrecisionSet."
1135+ wps = wp_set. wps[indices]
1136+ setups = wp_set. setups isa AbstractVector ? wp_set. setups[indices] : wp_set. setups
1137+ names = wp_set. names isa AbstractVector ? wp_set. names[indices] : wp_set. names
1138+ return WorkPrecisionSet (
1139+ wps, length (wps), wp_set. abstols, wp_set. reltols, wp_set. prob,
1140+ setups, names, wp_set. error_estimate, wp_set. numruns
1141+ )
1142+ end
1143+
10431144Base. length (wp:: WorkPrecision ) = wp. N
10441145Base. size (wp:: WorkPrecision ) = length (wp)
10451146Base. getindex (wp:: WorkPrecision , i:: Int ) = wp. times[i]
0 commit comments