source: branches/HeuristicLab.Problems.BioBoost/HeuristicLab.Problems.BioBoost/3.3/ProblemDescription/DistanceMatrix.cs @ 13071

Last change on this file since 13071 was 13071, checked in by gkronber, 7 years ago

#2499: added license headers and removed unused usings

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;
31
32namespace HeuristicLab.BioBoost.ProblemDescription {
33
34  [Item("DistanceMatrix", "Represents a space-efficient, symmetric distance matrix of double values.")]
35  [StorableClass]
36  public class DistanceMatrix : NamedItem, IStringConvertibleMatrix {
37
38    public new static Image StaticItemImage {
39      get { return Common.Resources.VSImageLibrary.Class; }
40    }
41
42    [Storable]
43    public int Size { get; private set; }
44
45    [Storable]
46    public double Max { get; private set; }
47
48    [Storable]
49    public double Min { get; private set; }
50
51    [Storable]
52    private IEnumerable<double> Values_Persistence {
53      get { return values; }
54      set { values = new List<double>(value);}
55    }
56
57    private List<double> values;
58
59    #region Construction & Cloning
60    [StorableConstructor]
61    protected DistanceMatrix(bool isDeserializing) : base(isDeserializing) { }
62    protected DistanceMatrix(DistanceMatrix original, Cloner cloner)
63      : base(original, cloner) {
64      values = original.values.ToList();
65      Size = original.Size;
66      Min = original.Min;
67      Max = original.Max;
68      Name = original.Name;
69    }
70    public DistanceMatrix() {
71      values = new List<double>();
72      Size = 0;
73      Min = Double.NaN;
74      Max = Double.NaN;
75      Name = this.ItemName;
76    }
77    public override IDeepCloneable Clone(Cloner cloner) {
78      return new DistanceMatrix(this, cloner);
79    }
80    #endregion
81
82    protected virtual bool Validate(string value, out string errorMessage) {
83      double val;
84      if (!double.TryParse(value, out val)) {
85        errorMessage = string.Format(
86          "Invalid Value (Valid Value Format: '{0}')",
87          FormatPatterns.GetDoubleFormatPattern());
88        return false;
89      } else {
90        errorMessage = string.Empty;
91        return true;
92      }
93    }
94
95    protected int GetLinearIndex(int row, int col) {
96      if (row >= col)
97        return row*(row + 1)/2 + col;
98      else
99        return col*(col + 1)/2 + row;
100    }
101
102    public double this[int row, int col] {
103      get {
104        var value = values[GetLinearIndex(row, col)];
105        return value >= 0 ? value :
106          row == col ? Max*2 : Max*4;
107      }
108      set {
109        var i = GetLinearIndex(row, col);
110        var oldValue = values[i];
111        values[GetLinearIndex(row, col)] = value;
112        CheckBounds(oldValue, value);
113        OnItemChanged(row, col);
114        OnToStringChanged();
115      }
116    }
117
118    protected void CheckBounds(double oldValue, double value) {
119      if (Double.IsNaN(Max) || value > Max) {
120        Max = value;
121      } else if (oldValue == Max) {
122        Max = values.Max();
123      }
124      if (Double.IsNaN(Min) || value < Min) {
125        Min = value;
126      } else if (oldValue == Min) {
127        Min = values.Min();
128      }
129    }
130
131    protected virtual string GetValue(int rowIndex, int columIndex) {
132      return this[rowIndex, columIndex].ToString(CultureInfo.InvariantCulture);
133    }
134
135    protected virtual bool SetValue(string value, int rowIndex, int columnIndex) {
136      double val;
137      if (double.TryParse(value, out val)) {
138        this[rowIndex, columnIndex] = val;
139        return true;
140      } else {
141        return false;
142      }
143    }
144
145    public void Load(IEnumerable<Tuple<string, string, double>> labeledValues, IEnumerable<string> finalOrder, double defaultValue) {
146      var dict = labeledValues.ToDictionary(t => new {x = t.Item1, y = t.Item2}, t => t.Item3);
147      var labels = finalOrder.ToList();
148      Size = labels.Count;
149      values.Clear();
150      for (int i = 0; i<Size; i++) {
151        for (int j = 0; j<=i; j++) {
152          double value;
153          if (dict.TryGetValue(new { x = labels[i], y = labels[j] }, out value)) {
154            values.Add(value);
155          } else if (dict.TryGetValue(new { x = labels[j], y = labels[i] }, out value)) {
156            values.Add(value);
157          } else {
158            values.Add(defaultValue);
159          }
160        }
161      }
162      Min = values.Min();
163      Max = values.Max();
164      OnRowNamesChanged();
165      OnColumnNamesChanged();
166      OnRowsChanged();
167      OnColumnsChanged();
168      OnReset();
169    }
170
171    public DistanceMatrix CopyAndRemoveIndices(IEnumerable<int> indices) {
172      var idx = new HashSet<int>(indices);
173      int ii = 0, jj = 0;
174      var dm = new DistanceMatrix {Size = Size - idx.Count};
175      for (int i = 0; i < Size; i++) {
176        if (!idx.Contains(i)) {
177          for (int j = 0; j <= i; j++) {
178            if (!idx.Contains(j)) {
179              //dm[ii, jj] = this[i, j];
180              dm.values.Add(this[i, j]);
181            }
182            jj++;
183          }
184        }
185        ii++;
186      }
187      dm.Min = dm.values.Count > 0 ? dm.values.Min() : 0;
188      dm.Max = dm.values.Count > 0 ? dm.values.Max() : 0;
189      OnRowNamesChanged();
190      OnColumnNamesChanged();
191      OnRowsChanged();
192      OnColumnsChanged();
193      OnReset();
194      return dm;
195    }
196
197    #region IStringConvertibleMatrix Members
198
199    public int Rows { get { return Size; } set { throw new NotImplementedException(); } }
200    public int Columns { get { return Size; } set { throw new NotImplementedException(); } }
201    public bool ReadOnly { get { return true; } }
202
203    public IEnumerable<string> RowNames {
204      get { return Enumerable.Range(0, Size).Select(i => i.ToString(CultureInfo.InvariantCulture)); }
205      set { throw new NotImplementedException(); }
206    }
207    public IEnumerable<string> ColumnNames {
208      get { return RowNames; }
209      set { throw new NotImplementedException(); }
210    }
211    public bool SortableView {
212      get { return false; }
213      set { throw new NotImplementedException(); }
214    }
215
216
217    bool IStringConvertibleMatrix.Validate(string value, out string errorMessage) {
218      return Validate(value, out errorMessage);
219    }
220    string IStringConvertibleMatrix.GetValue(int rowIndex, int columIndex) {
221      return GetValue(rowIndex, columIndex);
222    }
223    bool IStringConvertibleMatrix.SetValue(string value, int rowIndex, int columnIndex) {
224      return SetValue(value, rowIndex, columnIndex);
225    }
226
227    public event EventHandler RowsChanged;
228    public event EventHandler ColumnsChanged;
229    public event EventHandler RowNamesChanged;
230    public event EventHandler ColumnNamesChanged;
231    public event EventHandler Reset;
232    public event EventHandler<EventArgs<int, int>> ItemChanged;
233    public event EventHandler SortableViewChanged;
234
235    #endregion
236
237    #region Events
238    protected void OnRowsChanged() {
239      var handler = RowsChanged;
240      if (handler != null)
241        handler(this, EventArgs.Empty);
242    }
243    protected void OnColumnsChanged() {
244      var handler = ColumnsChanged;
245      if (handler != null)
246        handler(this, EventArgs.Empty);
247    }
248    protected void OnRowNamesChanged() {
249      var handler = RowNamesChanged;
250      if (handler != null)
251        handler(this, EventArgs.Empty);
252    }
253    protected void OnColumnNamesChanged() {
254      var handler = ColumnNamesChanged;
255      if (handler != null)
256        handler(this, EventArgs.Empty);
257    }
258    protected void OnReset() {
259      var handler = Reset;
260      if (handler != null)
261        handler(this, EventArgs.Empty);
262    }
263    protected void OnItemChanged(int row, int col) {
264      var handler = ItemChanged;
265      if (handler != null) {
266        handler(this, new EventArgs<int, int>(row, col));
267        if (row != col)
268          handler(this, new EventArgs<int, int>(col, row));
269      }
270    }
271    #endregion
272  }
273}
Note: See TracBrowser for help on using the repository browser.