Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
12/18/17 12:27:14 (6 years ago)
Author:
bwerth
Message:

#2850 added named weights and automatic adaption thereof

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/Weighted TSNE/3.4/TSNE/Distances/WeightedEuclideanDistance.cs

    r15487 r15531  
    2929using HeuristicLab.Parameters;
    3030using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
     31using HeuristicLab.Problems.DataAnalysis;
    3132
    3233namespace HeuristicLab.Algorithms.DataAnalysis {
     
    3435  [Item("WeightedEuclideanDistance", "A weighted norm function that uses Euclidean distance √(Σ(w[i]²*(p1[i]-p2[i])²))")]
    3536  public class WeightedEuclideanDistance : ParameterizedNamedItem, IDistance<IEnumerable<double>> {
     37    [Storable]
     38    private double[] weights;
    3639    public const string WeightsParameterName = "Weights";
    37     public IValueParameter<DoubleArray> WeigthsParameter {
     40    public IValueParameter<DoubleArray> WeightsParameter {
    3841      get { return (IValueParameter<DoubleArray>) Parameters[WeightsParameterName]; }
    3942    }
    4043
    4144    public DoubleArray Weights {
    42       get { return WeigthsParameter.Value; }
    43       set { WeigthsParameter.Value = value; }
     45      get { return WeightsParameter.Value; }
     46      set { WeightsParameter.Value = value; }
    4447    }
    4548
     
    5255    protected WeightedEuclideanDistance(WeightedEuclideanDistance original, Cloner cloner) : base(original, cloner) {
    5356      RegisterParameterEvents();
     57      weights = original.weights != null ? original.weights.ToArray() : null;
    5458    }
    5559    public override IDeepCloneable Clone(Cloner cloner) {
     
    5761    }
    5862    public WeightedEuclideanDistance() {
    59       Parameters.Add(new ValueParameter<DoubleArray>(WeightsParameterName, "The weights used to modify the euclidean distance."));
     63      Parameters.Add(new ValueParameter<DoubleArray>(WeightsParameterName, "The weights used to modify the euclidean distance.", new DoubleArray(new[] {1.0})));
    6064      RegisterParameterEvents();
    6165    }
     
    7680
    7781    public double Get(IEnumerable<double> a, IEnumerable<double> b) {
    78       return GetDistance(a, b, Weights);
     82      return GetDistance(a, b, weights);
    7983    }
    8084    public IComparer<IEnumerable<double>> GetDistanceComparer(IEnumerable<double> item) {
     
    8892    }
    8993
     94    public void AdaptToProblemData(IDataAnalysisProblemData problemData) {
     95      Weights = new DoubleArray(problemData.AllowedInputVariables.Select(v => Weights.ElementNames.Contains(v) ? GetWeight(v) : 1).ToArray())
     96        {ElementNames = problemData.AllowedInputVariables};
     97    }
     98    public void Initialize(IDataAnalysisProblemData problemData) {
     99      if (Weights.Length != problemData.AllowedInputVariables.Count()) throw new ArgumentException("Number of Weights does not match the number of input variables");
     100      weights = Weights.ElementNames.All(v => v == null || v.Equals(string.Empty)) ?
     101        Weights.ToArray() :
     102        problemData.AllowedInputVariables.Select(GetWeight).ToArray();
     103    }
     104    private double GetWeight(string v) {
     105      var w = Weights;
     106      var names = w.ElementNames.ToArray();
     107      for (var i = 0; i < w.Length; i++) if (names[i].Equals(v)) return w[i];
     108      throw new ArgumentException("weigth for " + v + " was requested but not specified.");
     109    }
    90110    private void RegisterParameterEvents() {
    91       WeigthsParameter.ValueChanged += OnWeightsArrayChanged;
    92       WeigthsParameter.Value.ItemChanged += OnWeightChanged;
     111      WeightsParameter.ValueChanged += OnWeightsArrayChanged;
     112      WeightsParameter.Value.ItemChanged += OnWeightChanged;
    93113    }
    94114    private void OnWeightChanged(object sender, EventArgs<int> e) {
    95       WeigthsParameter.Value.ItemChanged -= OnWeightChanged;
     115      WeightsParameter.Value.ItemChanged -= OnWeightChanged;
    96116      Weights[e.Value] = Math.Max(0, Weights[e.Value]);
    97       WeigthsParameter.Value.ItemChanged -= OnWeightChanged;
     117      WeightsParameter.Value.ItemChanged -= OnWeightChanged;
    98118    }
    99119    private void OnWeightsArrayChanged(object sender, EventArgs e) {
    100       for (int i = 0; i < Weights.Length; i++)
     120      for (var i = 0; i < Weights.Length; i++)
    101121        Weights[i] = Math.Max(0, Weights[i]);
    102       WeigthsParameter.Value.ItemChanged += OnWeightChanged;
     122      WeightsParameter.Value.ItemChanged += OnWeightChanged;
    103123    }
    104124  }
Note: See TracChangeset for help on using the changeset viewer.