source: addons/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/ProblemDescription/DistanceMatrix.cs @ 16575

Last change on this file since 16575 was 16575, checked in by gkronber, 3 years ago

#2520: changed HeuristicLab.BioBoost addon to compile with new HL.Persistence

File size: 8.6 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using HeuristicLab.Common;
23using HeuristicLab.Core;
24using HeuristicLab.Data;
25using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
26using System;
27using System.Collections.Generic;
28using System.Drawing;
29using System.Globalization;
30using System.Linq;
31using HEAL.Attic;
32
33namespace HeuristicLab.BioBoost.ProblemDescription {
34
35  [Item("DistanceMatrix", "Represents a space-efficient, symmetric distance matrix of double values.")]
36  [StorableType("108ABFA4-9CA2-43B5-850A-3B3F13BC271A")]
37  public class DistanceMatrix : NamedItem, IStringConvertibleMatrix {
38
39    public new static Image StaticItemImage {
40      get { return Common.Resources.VSImageLibrary.Class; }
41    }
42
43    [Storable]
44    public int Size { get; private set; }
45
46    [Storable]
47    public double Max { get; private set; }
48
49    [Storable]
50    public double Min { get; private set; }
51
52    [Storable]
53    private IEnumerable<double> Values_Persistence {
54      get { return values; }
55      set { values = new List<double>(value);}
56    }
57
58    private List<double> values;
59
60    #region Construction & Cloning
61    [StorableConstructor]
62    protected DistanceMatrix(StorableConstructorFlag _) : base(_) { }
63    protected DistanceMatrix(DistanceMatrix original, Cloner cloner)
64      : base(original, cloner) {
65      values = original.values.ToList();
66      Size = original.Size;
67      Min = original.Min;
68      Max = original.Max;
69      Name = original.Name;
70    }
71    public DistanceMatrix() {
72      values = new List<double>();
73      Size = 0;
74      Min = Double.NaN;
75      Max = Double.NaN;
76      Name = this.ItemName;
77    }
78    public override IDeepCloneable Clone(Cloner cloner) {
79      return new DistanceMatrix(this, cloner);
80    }
81    #endregion
82
83    protected virtual bool Validate(string value, out string errorMessage) {
84      double val;
85      if (!double.TryParse(value, out val)) {
86        errorMessage = string.Format(
87          "Invalid Value (Valid Value Format: '{0}')",
88          FormatPatterns.GetDoubleFormatPattern());
89        return false;
90      } else {
91        errorMessage = string.Empty;
92        return true;
93      }
94    }
95
96    protected int GetLinearIndex(int row, int col) {
97      if (row >= col)
98        return row*(row + 1)/2 + col;
99      else
100        return col*(col + 1)/2 + row;
101    }
102
103    public double this[int row, int col] {
104      get {
105        var value = values[GetLinearIndex(row, col)];
106        return value >= 0 ? value :
107          row == col ? Max*2 : Max*4;
108      }
109      set {
110        var i = GetLinearIndex(row, col);
111        var oldValue = values[i];
112        values[GetLinearIndex(row, col)] = value;
113        CheckBounds(oldValue, value);
114        OnItemChanged(row, col);
115        OnToStringChanged();
116      }
117    }
118
119    protected void CheckBounds(double oldValue, double value) {
120      if (Double.IsNaN(Max) || value > Max) {
121        Max = value;
122      } else if (oldValue == Max) {
123        Max = values.Max();
124      }
125      if (Double.IsNaN(Min) || value < Min) {
126        Min = value;
127      } else if (oldValue == Min) {
128        Min = values.Min();
129      }
130    }
131
132    protected virtual string GetValue(int rowIndex, int columIndex) {
133      return this[rowIndex, columIndex].ToString(CultureInfo.InvariantCulture);
134    }
135
136    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
137      double val;
138      if (double.TryParse(value, out val)) {
139        this[rowIndex, columnIndex] = val;
140        return true;
141      } else {
142        return false;
143      }
144    }
145
146    public void Load(IEnumerable<Tuple<string, string, double>> labeledValues, IEnumerable<string> finalOrder, double defaultValue) {
147      var dict = labeledValues.ToDictionary(t => new {x = t.Item1, y = t.Item2}, t => t.Item3);
148      var labels = finalOrder.ToList();
149      Size = labels.Count;
150      values.Clear();
151      for (int i = 0; i<Size; i++) {
152        for (int j = 0; j<=i; j++) {
153          double value;
154          if (dict.TryGetValue(new { x = labels[i], y = labels[j] }, out value)) {
155            values.Add(value);
156          } else if (dict.TryGetValue(new { x = labels[j], y = labels[i] }, out value)) {
157            values.Add(value);
158          } else {
159            values.Add(defaultValue);
160          }
161        }
162      }
163      Min = values.Min();
164      Max = values.Max();
165      OnRowNamesChanged();
166      OnColumnNamesChanged();
167      OnRowsChanged();
168      OnColumnsChanged();
169      OnReset();
170    }
171
172    public DistanceMatrix CopyAndRemoveIndices(IEnumerable<int> indices) {
173      var idx = new HashSet<int>(indices);
174      int ii = 0, jj = 0;
175      var dm = new DistanceMatrix {Size = Size - idx.Count};
176      for (int i = 0; i < Size; i++) {
177        if (!idx.Contains(i)) {
178          for (int j = 0; j <= i; j++) {
179            if (!idx.Contains(j)) {
180              //dm[ii, jj] = this[i, j];
181              dm.values.Add(this[i, j]);
182            }
183            jj++;
184          }
185        }
186        ii++;
187      }
188      dm.Min = dm.values.Count > 0 ? dm.values.Min() : 0;
189      dm.Max = dm.values.Count > 0 ? dm.values.Max() : 0;
190      OnRowNamesChanged();
191      OnColumnNamesChanged();
192      OnRowsChanged();
193      OnColumnsChanged();
194      OnReset();
195      return dm;
196    }
197
198    #region IStringConvertibleMatrix Members
199
200    public int Rows { get { return Size; } set { throw new NotImplementedException(); } }
201    public int Columns { get { return Size; } set { throw new NotImplementedException(); } }
202    public bool ReadOnly { get { return true; } }
203
204    public IEnumerable<string> RowNames {
205      get { return Enumerable.Range(0, Size).Select(i => i.ToString(CultureInfo.InvariantCulture)); }
206      set { throw new NotImplementedException(); }
207    }
208    public IEnumerable<string> ColumnNames {
209      get { return RowNames; }
210      set { throw new NotImplementedException(); }
211    }
212    public bool SortableView {
213      get { return false; }
214      set { throw new NotImplementedException(); }
215    }
216
217
218    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
219      return Validate(value, out errorMessage);
220    }
221    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
222      return GetValue(rowIndex, columIndex);
223    }
224    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
225      return SetValue(value, rowIndex, columnIndex);
226    }
227
228    public event EventHandler RowsChanged;
229    public event EventHandler ColumnsChanged;
230    public event EventHandler RowNamesChanged;
231    public event EventHandler ColumnNamesChanged;
232    public event EventHandler Reset;
233    public event EventHandler<EventArgs<int, int>> ItemChanged;
234    public event EventHandler SortableViewChanged;
235
236    #endregion
237
238    #region Events
239    protected void OnRowsChanged() {
240      var handler = RowsChanged;
241      if (handler != null)
242        handler(this, EventArgs.Empty);
243    }
244    protected void OnColumnsChanged() {
245      var handler = ColumnsChanged;
246      if (handler != null)
247        handler(this, EventArgs.Empty);
248    }
249    protected void OnRowNamesChanged() {
250      var handler = RowNamesChanged;
251      if (handler != null)
252        handler(this, EventArgs.Empty);
253    }
254    protected void OnColumnNamesChanged() {
255      var handler = ColumnNamesChanged;
256      if (handler != null)
257        handler(this, EventArgs.Empty);
258    }
259    protected void OnReset() {
260      var handler = Reset;
261      if (handler != null)
262        handler(this, EventArgs.Empty);
263    }
264    protected void OnItemChanged(int row, int col) {
265      var handler = ItemChanged;
266      if (handler != null) {
267        handler(this, new EventArgs<int, int>(row, col));
268        if (row != col)
269          handler(this, new EventArgs<int, int>(col, row));
270      }
271    }
272    #endregion
273  }
274}
Note: See TracBrowser for help on using the repository browser.