- Timestamp:
- 04/01/10 21:06:40 (14 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.Problems.DataAnalysis/3.3/Dataset.cs
r3246 r3253 1 1 #region License Information 2 2 /* HeuristicLab 3 * Copyright (C) 2002-20 08Heuristic and Evolutionary Algorithms Laboratory (HEAL)3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 4 * 5 5 * This file is part of HeuristicLab. … … 23 23 using System.Collections.Generic; 24 24 using System.Xml; 25 using HeuristicLab.Core;26 using HeuristicLab.Data;27 25 using System.Globalization; 28 26 using System.Text; 29 27 using System.Linq; 30 31 namespace HeuristicLab.DataAnalysis { 32 public sealed class Dataset : ItemBase { 28 using HeuristicLab.Core; 29 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable; 30 using HeuristicLab.Data; 31 using HeuristicLab.Common; 32 33 namespace HeuristicLab.Problems.DataAnalysis { 34 [Item("Dataset", "Represents a dataset containing data that should be analyzed.")] 35 [StorableClass] 36 public sealed class Dataset : NamedItem, IStringConvertibleMatrix { 33 37 private Dictionary<int, Dictionary<int, double>>[] cachedMeans; 34 38 private Dictionary<int, Dictionary<int, double>>[] cachedRanges; … … 39 43 } 40 44 41 public Dataset(double[,] samples) { 45 public Dataset(double[,] data) 46 : base() { 42 47 Name = "-"; 43 Rows = samples.GetLength(0); 44 Columns = samples.GetLength(1); 45 double[] values = new double[Rows * Columns]; 46 int i = 0; 47 for (int row = 0; row < Rows; row++) { 48 for (int column = 0; column < columns; column++) { 49 values[i++] = samples[row, column]; 50 } 51 } 52 Samples = values; 53 fireChangeEvents = true; 54 } 55 56 #region Properties 57 private string name; 58 public string Name { 59 get { return name; } 60 set { name = value; } 61 } 62 63 private int rows; 64 public int Rows { 65 get { return rows; } 66 set { rows = value; } 67 } 68 69 private int columns; 70 public int Columns { 71 get { return columns; } 72 set { 73 columns = value; 74 if (variableNames == null || variableNames.Length != columns) { 75 variableNames = new string[columns]; 76 } 77 } 78 } 79 80 private string[] variableNames; 48 Data = new DoubleMatrix(data); 49 string formatString = new StringBuilder().Append('#', (int)Math.Log10(this.data.Columns) + 1).ToString(); // >= 100 variables => ### 50 this.variableNames = new StringArray((from col in Enumerable.Range(1, this.data.Columns) 51 select "Var" + col.ToString(formatString)).ToArray()); 52 } 53 54 private StringArray variableNames; 81 55 public IEnumerable<string> VariableNames { 82 56 get { return variableNames; } 83 57 } 84 58 85 private double[] samples;86 p ublic double[] Samples{87 get { return samples; }59 private DoubleMatrix data; 60 private DoubleMatrix Data { 61 get { return data; } 88 62 set { 89 variableNames = Enumerable.Range(1, columns).Select(x => "Var" + x.ToString("###")).ToArray();90 scalingFactor = new double[columns];91 scalingOffset = new double[columns];92 for (int i = 0; i < scalingFactor.Length; i++) {93 scalingFactor[i] = 1.0;94 scalingOffset[i] = 0.0;63 if (data != value) { 64 if (value == null) throw new ArgumentNullException(); 65 if (data != null) DeregisterDataEvents(); 66 this.data = value; 67 RegisterDataEvents(); 68 OnReset(EventArgs.Empty); 95 69 } 96 samples = value;97 cachedValuesInvalidated = true;98 if (fireChangeEvents) FireChanged(); 99 }100 }101 102 private bool fireChangeEvents = true;103 public bool FireChangeEvents { 104 get { return fireChangeEvents; }105 set { fireChangeEvents = value; }106 }107 108 private double[] scalingFactor;109 public double [] ScalingFactor{110 get { return scalingFactor; }70 } 71 } 72 73 private void RegisterDataEvents() { 74 data.Reset += new EventHandler(data_Reset); 75 data.ItemChanged += new EventHandler<EventArgs<int, int>>(data_ItemChanged); 76 } 77 78 private void DeregisterDataEvents() { 79 data.Reset -= new EventHandler(data_Reset); 80 data.ItemChanged -= new EventHandler<EventArgs<int, int>>(data_ItemChanged); 81 } 82 // elementwise access 83 public double this[int rowIndex, int columnIndex] { 84 get { return data[rowIndex, columnIndex]; } 111 85 set { 112 if (value.Length != scalingFactor.Length) 113 throw new ArgumentException("Length of scaling factor array doesn't match number of variables"); 114 scalingFactor = value; 115 } 116 } 117 118 private double[] scalingOffset; 119 public double[] ScalingOffset { 120 get { return scalingOffset; } 121 set { 122 if (value.Length != scalingOffset.Length) 123 throw new ArgumentException("Length of scaling offset array doesn't match number of variables"); 124 scalingOffset = value; 125 } 126 } 127 #endregion 128 129 #region Modify and get values 130 public double GetValue(int row, int column) { 131 return samples[columns * row + column]; 132 } 133 134 public double[] GetVariableValues(int variableIndex, int start, int end) { 86 if (!value.Equals(data[rowIndex, columnIndex])) { 87 data[rowIndex, columnIndex] = value; 88 OnDataChanged(new EventArgs<int, int>(rowIndex, columnIndex)); 89 } 90 } 91 } 92 // access to full columns 93 public double[] this[string variableName] { 94 get { return VariableValues(VariableIndex(variableName), 0, data.Rows); } 95 } 96 97 public double[] VariableValues(int variableIndex, int start, int end) { 135 98 if (start < 0 || !(start <= end)) 136 99 throw new ArgumentException("Start must be between 0 and end (" + end + ")."); 137 if (end > rows || end < start)138 throw new ArgumentException("End must be between start (" + start + ") and dataset rows (" + rows + ").");100 if (end > data.Rows || end < start) 101 throw new ArgumentException("End must be between start (" + start + ") and dataset rows (" + data.Rows + ")."); 139 102 140 103 double[] values = new double[end - start]; 141 104 for (int i = 0; i < end - start; i++) 142 values[i] = GetValue(i + start, variableIndex);105 values[i] = data[i + start, variableIndex]; 143 106 return values; 144 107 } 145 108 146 public double[] GetVariableValues(int variableIndex) { 147 return GetVariableValues(variableIndex, 0, this.rows); 148 } 149 150 public double[] GetVariableValues(string variableName, int start, int end) { 151 return GetVariableValues(GetVariableIndex(variableName), start, end); 152 } 153 154 public double[] GetVariableValues(string variableName) { 155 return GetVariableValues(variableName, 0, this.rows); 156 } 157 158 public void SetValue(int i, int j, double v) { 159 if (v != samples[columns * i + j]) { 160 samples[columns * i + j] = v; 161 cachedValuesInvalidated = true; 162 if (fireChangeEvents) FireChanged(); 163 } 164 } 165 166 public IEnumerable<double> ReplaceVariableValues(int variableIndex, IEnumerable<double> newValues, int start, int end) { 167 double[] oldValues = new double[end - start]; 168 for (int i = 0; i < end - start; i++) oldValues[i] = this.GetValue(i + start, variableIndex); 169 if (newValues.Count() != end - start) throw new ArgumentException("The length of the new values sequence doesn't match the required length (number of replaced values)"); 170 171 int index = start; 172 this.FireChangeEvents = false; 173 foreach (double v in newValues) { 174 this.SetValue(index++, variableIndex, v); 175 } 176 this.FireChangeEvents = true; 177 this.FireChanged(); 178 return oldValues; 179 } 180 181 public IEnumerable<double> ReplaceVariableValues(string variableName, IEnumerable<double> newValues, int start, int end) { 182 return ReplaceVariableValues(this.GetVariableIndex(variableName), newValues, start, end); 183 } 184 #endregion 109 public double[] VariableValues(string variableName, int start, int end) { 110 return VariableValues(VariableIndex(variableName), start, end); 111 } 185 112 186 113 #region Variable name methods 187 public string GetVariableName(int variableIndex) {114 public string VariableName(int variableIndex) { 188 115 return variableNames[variableIndex]; 189 116 } 190 117 191 public int GetVariableIndex(string variableName) {118 public int VariableIndex(string variableName) { 192 119 for (int i = 0; i < variableNames.Length; i++) { 193 120 if (variableNames[i].Equals(variableName)) return i; … … 198 125 public void SetVariableName(int variableIndex, string name) { 199 126 variableNames[variableIndex] = name; 200 if (fireChangeEvents) FireChanged(); 201 } 202 203 public bool ContainsVariableName(string variableName) { 204 return this.variableNames.Contains(variableName); 205 } 127 } 128 206 129 #endregion 207 130 208 public override IView CreateView() { 209 return new DatasetView(this); 210 } 211 212 213 #region Variable statistics 214 public double GetMean(string variableName) { 215 return GetMean(GetVariableIndex(variableName)); 216 } 217 218 public double GetMean(string variableName, int start, int end) { 219 return GetMean(GetVariableIndex(variableName), start, end); 220 } 221 222 public double GetMean(int column) { 223 return GetMean(column, 0, Rows); 224 } 225 226 public double GetMean(int column, int start, int end) { 131 #region variable statistics 132 public double Mean(string variableName) { 133 return Mean(VariableIndex(variableName)); 134 } 135 136 public double Mean(string variableName, int start, int end) { 137 return Mean(VariableIndex(variableName), start, end); 138 } 139 140 public double Mean(int variableIndex) { 141 return Mean(variableIndex, 0, data.Rows); 142 } 143 144 public double Mean(int variableIndex, int start, int end) { 227 145 if (cachedValuesInvalidated) CreateDictionaries(); 228 if (!cachedMeans[column].ContainsKey(start) || !cachedMeans[column][start].ContainsKey(end)) { 229 double[] values = new double[end - start]; 230 for (int sample = start; sample < end; sample++) { 231 values[sample - start] = GetValue(sample, column); 232 } 233 double mean = Statistics.Mean(values); 234 if (!cachedMeans[column].ContainsKey(start)) cachedMeans[column][start] = new Dictionary<int, double>(); 235 cachedMeans[column][start][end] = mean; 146 if (!cachedMeans[variableIndex].ContainsKey(start) || !cachedMeans[variableIndex][start].ContainsKey(end)) { 147 double mean = VariableValues(variableIndex, start, end).Average(); 148 if (!cachedMeans[variableIndex].ContainsKey(start)) cachedMeans[variableIndex][start] = new Dictionary<int, double>(); 149 cachedMeans[variableIndex][start][end] = mean; 236 150 return mean; 237 151 } else { 238 return cachedMeans[ column][start][end];239 } 240 } 241 242 public double GetRange(string variableName) {243 return GetRange(this.GetVariableIndex(variableName));244 } 245 246 public double GetRange(int column) {247 return GetRange(column, 0,Rows);248 } 249 250 public double GetRange(string variableName, int start, int end) {251 return GetRange(this.GetVariableIndex(variableName), start, end);252 } 253 254 public double GetRange(int column, int start, int end) {152 return cachedMeans[variableIndex][start][end]; 153 } 154 } 155 156 public double Range(string variableName) { 157 return Range(VariableIndex(variableName)); 158 } 159 160 public double Range(int variableIndex) { 161 return Range(variableIndex, 0, data.Rows); 162 } 163 164 public double Range(string variableName, int start, int end) { 165 return Range(VariableIndex(variableName), start, end); 166 } 167 168 public double Range(int variableIndex, int start, int end) { 255 169 if (cachedValuesInvalidated) CreateDictionaries(); 256 if (!cachedRanges[column].ContainsKey(start) || !cachedRanges[column][start].ContainsKey(end)) { 257 double[] values = new double[end - start]; 258 for (int sample = start; sample < end; sample++) { 259 values[sample - start] = GetValue(sample, column); 260 } 261 double range = Statistics.Range(values); 262 if (!cachedRanges[column].ContainsKey(start)) cachedRanges[column][start] = new Dictionary<int, double>(); 263 cachedRanges[column][start][end] = range; 170 if (!cachedRanges[variableIndex].ContainsKey(start) || !cachedRanges[variableIndex][start].ContainsKey(end)) { 171 var values = VariableValues(variableIndex, start, end); 172 double range = values.Max() - values.Min(); 173 if (!cachedRanges[variableIndex].ContainsKey(start)) cachedRanges[variableIndex][start] = new Dictionary<int, double>(); 174 cachedRanges[variableIndex][start][end] = range; 264 175 return range; 265 176 } else { 266 return cachedRanges[column][start][end]; 267 } 268 } 269 270 public double GetMaximum(string variableName) { 271 return GetMaximum(this.GetVariableIndex(variableName)); 272 } 273 274 public double GetMaximum(int column) { 275 return GetMaximum(column, 0, Rows); 276 } 277 278 public double GetMaximum(string variableName, int start, int end) { 279 return GetMaximum(this.GetVariableIndex(variableName), start, end); 280 } 281 282 public double GetMaximum(int column, int start, int end) { 283 double max = Double.NegativeInfinity; 284 for (int i = start; i < end; i++) { 285 double val = GetValue(i, column); 286 if (!double.IsNaN(val) && val > max) max = val; 287 } 288 return max; 289 } 290 291 public double GetMinimum(string variableName) { 292 return GetMinimum(GetVariableIndex(variableName)); 293 } 294 295 public double GetMinimum(int column) { 296 return GetMinimum(column, 0, Rows); 297 } 298 299 public double GetMinimum(string variableName, int start, int end) { 300 return GetMinimum(this.GetVariableIndex(variableName), start, end); 301 } 302 303 public double GetMinimum(int column, int start, int end) { 304 double min = Double.PositiveInfinity; 305 for (int i = start; i < end; i++) { 306 double val = GetValue(i, column); 307 if (!double.IsNaN(val) && val < min) min = val; 308 } 309 return min; 310 } 311 312 public int CountMissingValues(string variableName) { 313 return CountMissingValues(this.GetVariableIndex(variableName)); 314 } 315 public int CountMissingValues(int column) { 316 return CountMissingValues(column, 0, Rows); 317 } 318 319 public int CountMissingValues(string variableName, int start, int end) { 320 return CountMissingValues(this.GetVariableIndex(variableName), start, end); 321 } 322 323 public int CountMissingValues(int column, int start, int end) { 324 int n = 0; 325 for (int i = start; i < end; i++) { 326 double val = GetValue(i, column); 327 if (double.IsNaN(val)) n++; 328 } 329 return n; 177 return cachedRanges[variableIndex][start][end]; 178 } 179 } 180 181 public double Max(string variableName) { 182 return Max(VariableIndex(variableName)); 183 } 184 185 public double Max(int variableIndex) { 186 return Max(variableIndex, 0, data.Rows); 187 } 188 189 public double Max(string variableName, int start, int end) { 190 return Max(VariableIndex(variableName), start, end); 191 } 192 193 public double Max(int variableIndex, int start, int end) { 194 return VariableValues(variableIndex, start, end).Max(); 195 } 196 197 public double Min(string variableName) { 198 return Min(VariableIndex(variableName)); 199 } 200 201 public double Min(int variableIndex) { 202 return Min(variableIndex, 0, data.Rows); 203 } 204 205 public double Min(string variableName, int start, int end) { 206 return Min(VariableIndex(variableName), start, end); 207 } 208 209 public double Min(int variableIndex, int start, int end) { 210 return VariableValues(variableIndex, start, end).Min(); 211 } 212 213 public int MissingValues(string variableName) { 214 return MissingValues(VariableIndex(variableName)); 215 } 216 public int MissingValues(int variableIndex) { 217 return MissingValues(variableIndex, 0, data.Rows); 218 } 219 220 public int MissingValues(string variableName, int start, int end) { 221 return MissingValues(VariableIndex(variableName), start, end); 222 } 223 224 public int MissingValues(int variableIndex, int start, int end) { 225 return VariableValues(variableIndex, start, end).Count(x => double.IsNaN(x)); 330 226 } 331 227 332 228 #endregion 333 334 internal void ScaleVariable(int column) {335 if (scalingFactor[column] == 1.0 && scalingOffset[column] == 0.0) {336 double min = GetMinimum(column);337 double max = GetMaximum(column);338 double range = max - min;339 if (range == 0) ScaleVariable(column, 1.0, -min);340 else ScaleVariable(column, 1.0 / range, -min);341 }342 cachedValuesInvalidated = true;343 if (fireChangeEvents) FireChanged();344 }345 346 internal void ScaleVariable(int column, double factor, double offset) {347 scalingFactor[column] = factor;348 scalingOffset[column] = offset;349 for (int i = 0; i < Rows; i++) {350 double origValue = samples[i * columns + column];351 samples[i * columns + column] = (origValue + offset) * factor;352 }353 cachedValuesInvalidated = true;354 if (fireChangeEvents) FireChanged();355 }356 357 internal void UnscaleVariable(int column) {358 if (scalingFactor[column] != 1.0 || scalingOffset[column] != 0.0) {359 for (int i = 0; i < rows; i++) {360 double scaledValue = samples[i * columns + column];361 samples[i * columns + column] = scaledValue / scalingFactor[column] - scalingOffset[column];362 }363 scalingFactor[column] = 1.0;364 scalingOffset[column] = 0.0;365 }366 cachedValuesInvalidated = true;367 if (fireChangeEvents) FireChanged();368 }369 229 370 230 private void CreateDictionaries() { 371 231 // keep a means and ranges dictionary for each column (possible target variable) of the dataset. 372 cachedMeans = new Dictionary<int, Dictionary<int, double>>[ columns];373 cachedRanges = new Dictionary<int, Dictionary<int, double>>[ columns];374 for (int i = 0; i < columns; i++) {232 cachedMeans = new Dictionary<int, Dictionary<int, double>>[data.Columns]; 233 cachedRanges = new Dictionary<int, Dictionary<int, double>>[data.Columns]; 234 for (int i = 0; i < data.Columns; i++) { 375 235 cachedMeans[i] = new Dictionary<int, Dictionary<int, double>>(); 376 236 cachedRanges[i] = new Dictionary<int, Dictionary<int, double>>(); … … 379 239 } 380 240 381 #region persistence 382 public override object Clone(IDictionary<Guid, object> clonedObjects) { 383 Dataset clone = new Dataset(); 384 clonedObjects.Add(Guid, clone); 385 double[] cloneSamples = new double[rows * columns]; 386 Array.Copy(samples, cloneSamples, samples.Length); 387 clone.rows = rows; 388 clone.columns = columns; 389 clone.Samples = cloneSamples; 390 clone.Name = Name; 391 clone.variableNames = new string[variableNames.Length]; 392 Array.Copy(variableNames, clone.variableNames, variableNames.Length); 393 Array.Copy(scalingFactor, clone.scalingFactor, columns); 394 Array.Copy(scalingOffset, clone.scalingOffset, columns); 241 public override IDeepCloneable Clone(Cloner cloner) { 242 Dataset clone = (Dataset)base.Clone(cloner); 243 clone.data = (DoubleMatrix)data.Clone(cloner); 244 clone.variableNames = (StringArray)variableNames.Clone(cloner); 395 245 return clone; 396 246 } 397 247 398 public override XmlNode GetXmlNode(string name, XmlDocument document, IDictionary<Guid, IStorable> persistedObjects) { 399 XmlNode node = base.GetXmlNode(name, document, persistedObjects); 400 XmlAttribute problemName = document.CreateAttribute("Name"); 401 problemName.Value = Name; 402 node.Attributes.Append(problemName); 403 XmlAttribute dim1 = document.CreateAttribute("Dimension1"); 404 dim1.Value = rows.ToString(CultureInfo.InvariantCulture.NumberFormat); 405 node.Attributes.Append(dim1); 406 XmlAttribute dim2 = document.CreateAttribute("Dimension2"); 407 dim2.Value = columns.ToString(CultureInfo.InvariantCulture.NumberFormat); 408 node.Attributes.Append(dim2); 409 XmlAttribute variableNames = document.CreateAttribute("VariableNames"); 410 variableNames.Value = GetVariableNamesString(); 411 node.Attributes.Append(variableNames); 412 XmlAttribute scalingFactorsAttribute = document.CreateAttribute("ScalingFactors"); 413 scalingFactorsAttribute.Value = GetString(scalingFactor); 414 node.Attributes.Append(scalingFactorsAttribute); 415 XmlAttribute scalingOffsetsAttribute = document.CreateAttribute("ScalingOffsets"); 416 scalingOffsetsAttribute.Value = GetString(scalingOffset); 417 node.Attributes.Append(scalingOffsetsAttribute); 418 node.InnerText = ToString(CultureInfo.InvariantCulture.NumberFormat); 419 return node; 420 } 421 422 public override void Populate(XmlNode node, IDictionary<Guid, IStorable> restoredObjects) { 423 base.Populate(node, restoredObjects); 424 Name = node.Attributes["Name"].Value; 425 rows = int.Parse(node.Attributes["Dimension1"].Value, CultureInfo.InvariantCulture.NumberFormat); 426 columns = int.Parse(node.Attributes["Dimension2"].Value, CultureInfo.InvariantCulture.NumberFormat); 427 428 variableNames = ParseVariableNamesString(node.Attributes["VariableNames"].Value); 429 if (node.Attributes["ScalingFactors"] != null) 430 scalingFactor = ParseDoubleString(node.Attributes["ScalingFactors"].Value); 431 else { 432 scalingFactor = new double[columns]; // compatibility with old serialization format 433 for (int i = 0; i < scalingFactor.Length; i++) scalingFactor[i] = 1.0; 434 } 435 if (node.Attributes["ScalingOffsets"] != null) 436 scalingOffset = ParseDoubleString(node.Attributes["ScalingOffsets"].Value); 437 else { 438 scalingOffset = new double[columns]; // compatibility with old serialization format 439 for (int i = 0; i < scalingOffset.Length; i++) scalingOffset[i] = 0.0; 440 } 441 442 string[] tokens = node.InnerText.Split(';'); 443 if (tokens.Length != rows * columns) throw new FormatException(); 444 samples = new double[rows * columns]; 445 for (int row = 0; row < rows; row++) { 446 for (int column = 0; column < columns; column++) { 447 if (double.TryParse(tokens[row * columns + column], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out samples[row * columns + column]) == false) { 448 throw new FormatException("Can't parse " + tokens[row * columns + column] + " as double value."); 248 #region events 249 public event EventHandler<EventArgs<int, int>> DataChanged; 250 private void OnDataChanged(EventArgs<int, int> e) { 251 cachedValuesInvalidated = true; 252 253 var listeners = DataChanged; 254 if (listeners != null) listeners(this, e); 255 } 256 public event EventHandler Reset; 257 private void OnReset(EventArgs e) { 258 cachedValuesInvalidated = true; 259 260 var listeners = Reset; 261 if (listeners != null) listeners(this, e); 262 } 263 264 private void data_ItemChanged(object sender, EventArgs<int, int> e) { 265 OnDataChanged(e); 266 } 267 268 private void data_Reset(object sender, EventArgs e) { 269 OnReset(e); 270 } 271 #endregion 272 273 #region IStringConvertibleMatrix Members 274 275 public int Rows { 276 get { 277 return data.Rows + 1; 278 } 279 set { 280 if (value == 0) throw new ArgumentException("Number of rows must be at least one (for variable names)"); 281 if (value - 1 != data.Rows) { 282 var newValues = new double[value - 1, data.Columns]; 283 for (int row = 0; row < Math.Min(data.Rows, value - 1); row++) { 284 for (int column = 0; column < data.Columns; column++) { 285 newValues[row, column] = data[row, column]; 286 } 449 287 } 288 Data = new DoubleMatrix(newValues); 450 289 } 451 290 } 452 291 } 453 292 454 public override string ToString() { 455 return ToString(CultureInfo.CurrentCulture.NumberFormat); 456 } 457 458 private string ToString(NumberFormatInfo format) { 459 StringBuilder builder = new StringBuilder(); 460 for (int row = 0; row < rows; row++) { 461 for (int column = 0; column < columns; column++) { 462 builder.Append(";"); 463 builder.Append(samples[row * columns + column].ToString("r", format)); 293 public int Columns { 294 get { 295 return data.Columns; 296 } 297 set { 298 if (value != data.Columns) { 299 var newValues = new double[data.Rows, value]; 300 var newVariableNames = new string[value]; 301 for (int row = 0; row < data.Rows; row++) { 302 for (int column = 0; column < Math.Min(value, data.Columns); column++) { 303 newValues[row, column] = data[row, column]; 304 } 305 } 306 string formatString = new StringBuilder().Append('#', (int)Math.Log10(value) + 1).ToString(); // >= 100 variables => ### 307 for (int column = 0; column < value; column++) { 308 if (column < data.Columns) 309 newVariableNames[column] = variableNames[column]; 310 else 311 newVariableNames[column] = "Var" + column.ToString(formatString); 312 } 313 variableNames = new StringArray(newVariableNames); 314 Data = new DoubleMatrix(newValues); 464 315 } 465 316 } 466 if (builder.Length > 0) builder.Remove(0, 1); 467 return builder.ToString(); 468 } 469 470 private string GetVariableNamesString() { 471 string s = ""; 472 for (int i = 0; i < variableNames.Length; i++) { 473 s += variableNames[i] + "; "; 474 } 475 476 if (variableNames.Length > 0) { 477 s = s.TrimEnd(';', ' '); 478 } 479 return s; 480 } 481 private string GetString(double[] xs) { 482 string s = ""; 483 for (int i = 0; i < xs.Length; i++) { 484 s += xs[i].ToString("r", CultureInfo.InvariantCulture) + "; "; 485 } 486 487 if (xs.Length > 0) { 488 s = s.TrimEnd(';', ' '); 489 } 490 return s; 491 } 492 493 private string[] ParseVariableNamesString(string p) { 494 p = p.Trim(); 495 string[] tokens = p.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); 496 for (int i = 0; i < tokens.Length; i++) tokens[i] = tokens[i].Trim(); 497 return tokens; 498 } 499 private double[] ParseDoubleString(string s) { 500 s = s.Trim(); 501 string[] ss = s.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); 502 double[] xs = new double[ss.Length]; 503 for (int i = 0; i < xs.Length; i++) { 504 xs[i] = double.Parse(ss[i], CultureInfo.InvariantCulture); 505 } 506 return xs; 507 } 317 } 318 319 public bool Validate(string value, out string errorMessage) { 320 errorMessage = string.Empty; 321 return true; 322 } 323 324 public string GetValue(int rowIndex, int columnIndex) { 325 if (rowIndex == 0) { 326 // return variable name 327 return variableNames[columnIndex]; 328 } else { 329 return data[rowIndex - 1, columnIndex].ToString(); 330 } 331 } 332 333 public bool SetValue(string value, int rowIndex, int columnIndex) { 334 if (rowIndex == 0) { 335 // set variable name 336 variableNames[columnIndex] = value; 337 return true; 338 } else { 339 double v; 340 if (double.TryParse(value, out v)) { 341 data[rowIndex - 1, columnIndex] = v; 342 return true; 343 } else return false; 344 } 345 } 346 347 public event EventHandler<EventArgs<int, int>> ItemChanged; 348 508 349 #endregion 509 350 }
Note: See TracChangeset
for help on using the changeset viewer.