| File: Option\UniformNumericOption.cs | Web Access |
| Project: src\src\Microsoft.ML.SearchSpace\Microsoft.ML.SearchSpace.csproj (Microsoft.ML.SearchSpace) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Diagnostics.Contracts; using System.Linq; using System.Text.Json.Serialization; using Microsoft.ML.SearchSpace.Converter; namespace Microsoft.ML.SearchSpace.Option { /// <summary> /// abstract class for numeric option. /// </summary> [JsonConverter(typeof(NumericOptionConverter))] public abstract class UniformNumericOption : OptionBase { /// <summary> /// Create a <see cref="UniformNumericOption"/> using <paramref name="min"/> and <paramref name="max"/>. /// </summary> /// <param name="min"></param> /// <param name="max"></param> /// <param name="logBase">Indicate whether it should be log base or not.</param> public UniformNumericOption(double min, double max, bool logBase = false) { Contract.Assert(max > min, "max must be larger than min."); Contract.Assert(min > 0 || logBase == false, "min must be larger than 0 if logBase is true."); Min = min; Max = max; LogBase = logBase; Default = Enumerable.Repeat(0.0, FeatureSpaceDim).ToArray(); } /// <summary> /// Gets minimum value of this option. /// </summary> public double Min { get; } /// <summary> /// Gets maximum value of this option. /// </summary> public double Max { get; } /// <summary> /// Gets if this option is log base or not. /// </summary> public bool LogBase { get; } /// <inheritdoc/> public override int FeatureSpaceDim => 1; /// <inheritdoc/> public override int?[] Step => new int?[] { null }; /// <inheritdoc/> public override double[] MappingToFeatureSpace(Parameter param) { var x = param.AsType<double>(); Contract.Assert(x <= Max && x >= Min, $"{x} is not within [{Min}, {Max}]"); if (LogBase) { var logMax = Math.Log(Max); var logMin = Math.Log(Min); var logX = Math.Log(x); return new[] { logX / (logMax - logMin) - logMin / (logMax - logMin) }; } else { return new[] { x / (Max - Min) - Min / (Max - Min) }; } } /// <inheritdoc/> public override Parameter SampleFromFeatureSpace(double[] values) { Contract.Assert(values.Length == 1, "values length must be 1"); var value = values[0]; Contract.Assert(value <= 1 && value >= 0, $"{value} must be between [0,1]"); if (LogBase) { var order = Math.Pow(Max / Min, value); var res = Min * order; return Parameter.FromDouble(res); } else { return Parameter.FromDouble((Min + (Max - Min) * value)); } } } /// <summary> /// class for uniform double option. /// </summary> public sealed class UniformDoubleOption : UniformNumericOption { /// <summary> /// Create a <see cref="UniformDoubleOption"/> using <paramref name="min"/>, <paramref name="max"/> and <paramref name="defaultValue"/>. /// </summary> /// <param name="min"></param> /// <param name="max"></param> /// <param name="logBase"></param> /// <param name="defaultValue"></param> public UniformDoubleOption(double min, double max, bool logBase = false, double? defaultValue = null) : base(min, max, logBase) { if (defaultValue != null) { Default = MappingToFeatureSpace(Parameter.FromDouble(defaultValue.Value)); } } } /// <summary> /// class for uniform single option. /// </summary> public sealed class UniformSingleOption : UniformNumericOption { /// <summary> /// Create a <see cref="UniformSingleOption"/> using <paramref name="min"/>, <paramref name="max"/> and <paramref name="defaultValue"/>. /// </summary> /// <param name="min"></param> /// <param name="max"></param> /// <param name="logBase"></param> /// <param name="defaultValue"></param> public UniformSingleOption(float min, float max, bool logBase = false, float? defaultValue = null) : base(min, max, logBase) { if (defaultValue != null) { Default = MappingToFeatureSpace(Parameter.FromFloat(defaultValue.Value)); } } /// <inheritdoc/> public override double[] MappingToFeatureSpace(Parameter param) { var singleValue = param.AsType<float>(); var doubleValue = Convert.ToDouble(singleValue); return base.MappingToFeatureSpace(Parameter.FromDouble(doubleValue)); } /// <inheritdoc/> public override Parameter SampleFromFeatureSpace(double[] values) { var doubleValue = base.SampleFromFeatureSpace(values).AsType<double>(); var singleValue = Convert.ToSingle(doubleValue); return Parameter.FromFloat(singleValue); } } /// <summary> /// class for uniform int option. /// </summary> public sealed class UniformIntOption : UniformNumericOption { /// <summary> /// Create a <see cref="UniformIntOption"/> using <paramref name="min"/>, <paramref name="max"/> and <paramref name="defaultValue"/>. /// </summary> /// <param name="min"></param> /// <param name="max"></param> /// <param name="logBase"></param> /// <param name="defaultValue"></param> public UniformIntOption(int min, int max, bool logBase = false, int? defaultValue = null) : base(min, max, logBase) { if (defaultValue != null) { Default = MappingToFeatureSpace(Parameter.FromInt(defaultValue.Value)); } } /// <inheritdoc/> public override Parameter SampleFromFeatureSpace(double[] values) { var param = base.SampleFromFeatureSpace(values); var intValue = Convert.ToInt32(Math.Floor(param.AsType<double>())); return Parameter.FromInt(intValue); } /// <inheritdoc/> public override double[] MappingToFeatureSpace(Parameter param) { var value = param.AsType<int>(); var valueAsDouble = Convert.ToDouble(value); return base.MappingToFeatureSpace(Parameter.FromDouble(valueAsDouble)); } } }