1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_POWER_AUTO_SCREEN_BRIGHTNESS_GAUSSIAN_TRAINER_H_
#define CHROME_BROWSER_ASH_POWER_AUTO_SCREEN_BRIGHTNESS_GAUSSIAN_TRAINER_H_
#include <memory>
#include "chrome/browser/ash/power/auto_screen_brightness/trainer.h"
namespace ash {
namespace power {
namespace auto_screen_brightness {
struct TrainingResult {
TrainingResult();
TrainingResult(const std::optional<MonotoneCubicSpline>& new_curve,
double error);
TrainingResult(const TrainingResult& result);
~TrainingResult();
// |new_curve| will be nullopt if trainer's curve stays unchanged after
// training.
std::optional<MonotoneCubicSpline> new_curve;
// Evaluation error of the latest curve (possibly updated) using the training
// data points.
double error;
};
// GaussianTrainer updates an existing brightness curve (a mapping from
// ambient light to screen brightness) using training data points that represent
// how user changes brightness following an ambient value change. The update
// procedure is Gaussian hence the name. It uses a global curve to check for
// outliers that may exist in training data. It also ensures new curves are
// monotone and also satisfy requirements on the slope.
class GaussianTrainer : public Trainer {
public:
// TODO(jiameng): revise default values.
struct Params {
Params();
// |brightness_bound_scale| and |brightness_bound_offset| are used to define
// training example outliers.
double brightness_bound_scale = 1.5;
double brightness_bound_offset = 40;
// |brightness_step_size| defines reasonable brightness change scale: a
// reasonable change would be between
// brightness_old/(1+|brightness_step_size|) and
// brightness_old*(1+|brightness_step_size|)
double brightness_step_size = 1.5;
// Similar to |brightness_step_size| except it defines reasonable brightness
// change scale between target brightness and model predicted brightness.
double model_brightness_step_size = 2.0;
// One training data point could modify all the points on the curve, but its
// effect is greatest on the point nearest to it (as measured by difference
// in ambient value). The effect on the other points decay with a Gaussian
// distribution with standard deviation |sigma|.
double sigma = 1;
// If log lux is below |low_log_lux_threshold| then we'll use
// |min_grad_low_lux| as gradient constraint.
double low_log_lux_threshold = 0.1;
double min_grad_low_lux = 0;
// If log lux is above |high_log_lux_threshold| then we'll use
// |min_grad_high_lux| as gradient constraint.
double high_log_lux_threshold = 7.5;
double min_grad_high_lux = 0;
// Min and max grad as a power of brightness ratios.
double min_grad = 0.25;
double max_grad = 1;
double min_brightness = 0;
};
GaussianTrainer();
GaussianTrainer(const GaussianTrainer&) = delete;
GaussianTrainer& operator=(const GaussianTrainer&) = delete;
~GaussianTrainer() override;
// Trainer overrides:
bool HasValidConfiguration() const override;
bool SetInitialCurves(const MonotoneCubicSpline& global_curve,
const MonotoneCubicSpline& current_curve) override;
MonotoneCubicSpline GetGlobalCurve() const override;
MonotoneCubicSpline GetCurrentCurve() const override;
TrainingResult Train(const std::vector<TrainingDataPoint>& data) override;
private:
// Returns whether initial personal curve (passed in by |SetInitialCurves|) is
// valid, i.e. satisfying min/max ratio constraints.
bool IsInitialPersonalCurveValid() const;
// Updates |brightness_| using |data|. It also sets |need_to_update_curve_|
// to true if |brightness_| is actually changed.
void AdjustCurveWithSingleDataPoint(const TrainingDataPoint& data);
// Called each time |AdjustCurveWithSingleDataPoint| changes |brightness_|.
// It ensures the curve is still monotone and also satisfies min/max grad
// constraints. It does this by changing points to the left and to the right
// of |center_index|.
void EnforceMonotonicity(size_t center_index);
// Calculates (possibly) updated curve's MAE error w.r.t. |data|. The error
// will be in the range of [0, 100].
double CalculateCurveError(const std::vector<TrainingDataPoint>& data) const;
// Default params_ are valid.
bool valid_params_ = true;
Params params_;
// |global_curve| does not change after |SetInitialCurves| is called.
std::optional<MonotoneCubicSpline> global_curve_;
// |current_curve_| initially is set by |SetInitialCurves| and then gets
// updated during training.
std::optional<MonotoneCubicSpline> current_curve_;
// Whether the |brightness_| has been updated since last time |Train| updated
// the curve.
bool need_to_update_curve_ = false;
// (|ambient_log_lux_|, |brightness_|) are the control points of
// |current_curve_|. |ambient_log_lux_| doesn't change, but |brightness_| may
// be updated during training.
std::vector<double> ambient_log_lux_;
std::vector<double> brightness_;
// Minimum and max brightness ratios of two adjacent control points. They are
// calculated from the global curve's brightness values.
std::vector<double> min_ratios_;
std::vector<double> max_ratios_;
};
} // namespace auto_screen_brightness
} // namespace power
} // namespace ash
#endif // CHROME_BROWSER_ASH_POWER_AUTO_SCREEN_BRIGHTNESS_GAUSSIAN_TRAINER_H_
|