Class JanusSampler
- Namespace
- OptunaSharp.Samplers
- Assembly
- OptunaSharp.dll
A plug-and-play, training-free JANUS sampler. JANUS estimates a local Jacobian from the recent
evaluation trace and uses the same Jacobian for both a damped Gauss–Newton exploitation
candidate (bounded-injected into the population) and a trace-preserving inverse-curvature
exploration metric (a fraction of the offspring), while a CMA-ES host keeps full control of
selection, covariance adaptation, and step-size control. Port of the authors' reference
janus_optuna.JanusSampler (arXiv:2608.22862; https://github.com/hongyuanyu/JANUS).
JANUS-GN vs full JANUS. Passing cmixCandidateFrac: 0 (or cmixMode:
"none") disables the CMIX exploration candidates, leaving only the Gauss–Newton
exploitation injection — the paper's conservative JANUS-GN variant. The default is full
JANUS (GN + CMIX).
Residual coordinates (optional but recommended). If the objective decomposes into
components f(x) = mean_i r_i(x), expose the residual vector on each trial via
trial.SetUserAttr("component_losses", new double[]{ r1, r2, … }); JANUS then estimates
the local Jacobian directly from those residuals, where its geometric signal is sharpest.
Without it, JANUS falls back to a local linear/quadratic fit on the recent window of scalar
objective values (the paper's BBOB "scalar residual coordinate" mode — see pseudoMode).
Beyond-core, in-memory state. Unlike CmaEsSampler, which serializes its optimizer into trial system attrs (for RDB / distributed resume), JANUS holds its optimizer in memory for the study's duration — matching the reference implementation. A JANUS study therefore does not resume its infill state across process boundaries. Categorical and single-value distributions are handled by the independent sampler, as in CmaEsSampler.
public sealed class JanusSampler : BaseSampler
- Inheritance
-
JanusSampler
- Inherited Members
Examples
var study = Optuna.CreateStudy(sampler: new JanusSampler(seed: 0, nStartupTrials: 16));
study.Optimize(t =>
{
double s = 0;
for (int i = 0; i < 10; i++) { double x = t.SuggestFloat($"x{i}", -5, 5); double r = (x - 0.5) * (x - 0.5); s += r; }
return s;
}, nTrials: 300);
Constructors
JanusSampler(double?, int?, int?, int, BaseSampler?, bool, int, int, int?, double, int?, double, double, double?, double, double, double, double, string, string?, string?, string, string, string, double, string)
Configures Jacobian-informed candidates injected into a CMA-ES population.
public JanusSampler(double? sigma0 = null, int? seed = null, int? popsize = null, int nStartupTrials = 1, BaseSampler? independentSampler = null, bool warnIndependentSampling = true, int nJobs = 1, int fuseEvery = 4, int? fuseStart = null, double kappa = 1, int? gnWindow = null, double gnLambda = 1, double gnRidge = 1, double? cmixW = null, double cmixLambda = 1, double cmixWBase = 0.5, double cmixWMin = 0.01, double cmixWMax = 0.2, string pseudoMode = "linear", string? gnPseudoMode = null, string? cmixPseudoMode = null, string pseudoTarget = "raw", string pcaK = "auto", string cmixMode = "portfolio", double cmixCandidateFrac = 0.4, string cmixCandidateCenter = "mean")
Parameters
sigma0double?Initial CMA-ES step size (accepted for signature parity; the host's initial step is
min_range/6in the transformed box, as in the reference).seedint?Random seed. When
null, a random seed is drawn.popsizeint?Population size λ (default
4 + ⌊3 ln d⌋).nStartupTrialsintIndependent sampling is used until this many trials finish.
independentSamplerBaseSamplerSampler for parameters outside the relative space (default RandomSampler).
warnIndependentSamplingboolWarn when a parameter is sampled independently.
nJobsintNumber of parallel workers; a separate optimizer is kept per
trial.Number % nJobs(as in the reference).fuseEveryintGenerations between Jacobian re-estimation (assembly cadence).
fuseStartint?Window size before the first Jacobian assembly (
null= auto).kappadoubleBounded-injection clip factor (whitened step ‖z‖ ≤ κ√d).
gnWindowint?Sliding window of recent
(x, f)pairs for the Jacobian regression (null= auto).gnLambdadoubleLevenberg–Marquardt damping for the Gauss–Newton step.
gnRidgedoubleRidge regularization for the residual-gradient regression.
cmixWdouble?CMIX absolute mixing weight for the reshape mode (
null= auto); unused by the default candidate/portfolio mode.cmixLambdadoubleLevenberg–Marquardt damping for the CMIX inverse-curvature metric.
cmixWBasedoubleBase CMIX mixing weight before dimension scaling.
cmixWMindoubleCompatibility argument retained by the public constructor; currently not used by the driver.
cmixWMaxdoubleUpper clip for the auto CMIX mixing weight.
pseudoModestringScalar residual-coordinate fit:
linear(default),quadratic,diag_quadratic,pca_quadratic,diag_pca_quadratic, ornone.gnPseudoModestringOverride
pseudoModefor the GN direction (null= same).cmixPseudoModestringOverride
pseudoModefor the CMIX metric (null= same).pseudoTargetstringScalar-value transform for the fit:
raw(default),rank, orlog.pcaKstringPCA rank for the
pca_quadraticfit (autoor an integer string).cmixModestringportfolio(default) /candidatesdraw CMIX samples into tail slots;reshapemixes the inverse-curvature metric into the host covariance in place (component mode; no-op on a covariance-free host);nonedisables CMIX (JANUS-GN).cmixCandidateFracdoubleFraction of offspring drawn from the JANUS exploration metric (default 0.4). Set to 0 for JANUS-GN.
cmixCandidateCenterstringCenter of the CMIX samples:
mean(default),best,elite, orarchive(a diverse Pareto-archive of residual-window points, round-robined).
Methods
AfterTrial(Study, FrozenTrial, TrialState, IReadOnlyList<double>?)
Trial post-processing: called after the objective function returns and right before the trial is finished and its state is stored.
public override void AfterTrial(Study study, FrozenTrial trial, TrialState state, IReadOnlyList<double>? values)
Parameters
studyStudyStudy that owns the trial being finished.
trialFrozenTrialTrial snapshot before its terminal state is written to storage.
stateTrialStateTerminal state being recorded: complete, pruned, or failed.
valuesIReadOnlyList<double>Resulting trial values in objective order; non-null for a successful trial.
BeforeTrial(Study, FrozenTrial)
Trial pre-processing: called during trial initialization, just before the InferRelativeSearchSpace(Study, FrozenTrial) call.
public override void BeforeTrial(Study study, FrozenTrial trial)
Parameters
studyStudyStudy that owns the newly initialized trial.
trialFrozenTrialNew trial snapshot available before search-space inference.
InferRelativeSearchSpace(Study, FrozenTrial)
Infer the search space that will be used by relative sampling in the target trial.
This method is called right before SampleRelative(Study, FrozenTrial, OrderedDict<string, BaseDistribution>), and the search space returned by this method is passed to it. The parameters not contained in the search space will be sampled by using SampleIndependent(Study, FrozenTrial, string, BaseDistribution).
public override OrderedDict<string, BaseDistribution> InferRelativeSearchSpace(Study study, FrozenTrial trial)
Parameters
studyStudyStudy supplying trial history, directions, and storage.
trialFrozenTrialCurrent trial snapshot; copy it before modifying its contents.
Returns
- OrderedDict<string, BaseDistribution>
Parameter distributions eligible for joint sampling, in sampler-defined order.
ReseedRng()
Reseed sampler's random number generator.
Parallel optimization calls this hook before a worker's sequential trial loop. Concrete samplers refresh their random streams so workers do not deliberately reuse a seeded sequence. OptunaSharp workers share the study's sampler instance; this hook does not clone it or make concurrent sampling reproducible.
public override void ReseedRng()
SampleIndependent(Study, FrozenTrial, string, BaseDistribution)
Sample a parameter for a given distribution.
This method is called only for the parameters not contained in the search space returned by SampleRelative(Study, FrozenTrial, OrderedDict<string, BaseDistribution>). This method is suitable for sampling algorithms that do not use relationship between parameters such as random sampling and TPE.
public override object? SampleIndependent(Study study, FrozenTrial trial, string paramName, BaseDistribution paramDistribution)
Parameters
studyStudyStudy supplying trial history, directions, and storage.
trialFrozenTrialCurrent trial snapshot; copy it before modifying its contents.
paramNamestringName of the parameter being suggested.
paramDistributionBaseDistributionDistribution defining the parameter's domain and scale.
Returns
- object
A value in the distribution's external representation, including null categorical choices.
Exceptions
- ValueError
The study has multiple objectives, but this sampler requires a scalar objective.
SampleRelative(Study, FrozenTrial, OrderedDict<string, BaseDistribution>)
Sample parameters in a given search space.
The trial invokes this method lazily when it first needs relative parameters and caches the result for its remaining suggestions. This method is suitable for sampling algorithms that use relationship between parameters such as Gaussian Process and CMA-ES.
public override OrderedDict<string, object?> SampleRelative(Study study, FrozenTrial trial, OrderedDict<string, BaseDistribution> searchSpace)
Parameters
studyStudyStudy supplying trial history, directions, and storage.
trialFrozenTrialCurrent trial snapshot; copy it before modifying its contents.
searchSpaceOrderedDict<string, BaseDistribution>Distributions returned by InferRelativeSearchSpace(Study, FrozenTrial).
Returns
- OrderedDict<string, object>
Jointly sampled external parameter values; omitted parameters use independent sampling.
Exceptions
- ValueError
The study has multiple objectives, but this sampler requires a scalar objective.