Changeset 10200
- Timestamp:
- 12/06/13 20:45:07 (11 years ago)
- Location:
- branches/HeuristicLab.Analysis.AlgorithmBehavior
- Files:
-
- 7 added
- 1 deleted
- 7 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/ConvexHullMeasures.cs
r10198 r10200 29 29 //Calculates the volumne of a d-simplex 30 30 private static double CalculateSimplexVolume(List<double[]> simplex) { 31 double[,] diffs = new double[simplex.Count, simplex.Count]; 31 int dim = simplex.First().Length; 32 double[,] diffs = new double[dim, dim]; 32 33 33 for (int i = 0; i < simplex.Count; i++) {34 for (int j = 0; j < simplex.Count; j++) {35 diffs[ i, j] = simplex[i].EuclideanDistance(simplex[j]);34 for (int i = 1; i < simplex.Count; i++) { 35 for (int j = 0; j < dim; j++) { 36 diffs[j, i - 1] = simplex[i][j] - simplex[0][j]; 36 37 } 37 38 } 38 39 39 40 double det = alglib.rmatrixdet(diffs); 40 double result = det / simplex[0].Count().Fact();41 double result = det / dim.Fact(); 41 42 42 43 return result; -
branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/FractionClass.cs
r10198 r10200 1 /* 2 * Author: Syed Mehroz Alam 3 * Email: smehrozalam@yahoo.com 4 * URL: Programming Home "http://www.geocities.com/smehrozalam/" 5 * 6 */ 7 8 using System; 9 using System.Runtime.InteropServices; 10 using System.Globalization; 11 12 namespace Mehroz 13 { 14 /// <summary> 15 /// Classes Contained: 16 /// Fraction 17 /// FractionException 18 /// </summary> 19 20 /// Class name: Fraction 21 /// Developed by: Syed Mehroz Alam 22 /// Email: mailto:smehrozalam@yahoo.com 23 /// URL: http://www.geocities.com/smehrozalam/ 24 /// Changes: Marc C. Brooks mailto:IDisposable@gmail.com 25 /// Jeffery Sax http://www.extremeoptimization.com 26 /// Version: 2.2 27 /// 28 /// What's new in version 2.0: 29 /// * Changed Numerator and Denominator from Int32(integer) to Int64(long) for increased range 30 /// * renamed ConvertToString() to (overloaded) ToString() 31 /// * added the capability of detecting/raising overflow exceptions 32 /// * Fixed the bug that very small numbers e.g. 0.00000001 could not be converted to fraction 33 /// * Other minor bugs fixed 34 /// 35 /// What's new in version 2.1 36 /// * overloaded user-defined conversions to/from Fractions 37 /// 38 /// What's new in version 2.2 - Marc C. Brooks mailto:IDisposable@gmail.com 39 /// * less overflows by finding the GCD for Add [Jeffery Sax] and Multiply [Marc C. Brooks] 40 /// * understands and handles NaN, PositiveInfinity, NegativeInfinity just like double [Marc C. Brooks] 41 /// * fixed several uses of int where long was correct [Marc C. Brooks] 42 /// * made value-type (struct) [Jeffery Sax] 43 /// * added ToInt32(), ToInt64() which throw for invalid (NaN, PositiveInfinity, NegativeInfinity) [Marc C. Brooks] 44 /// * removed redundant Value property [Jeffery Sax] 45 /// * added explicit conversion to Int32 and Int64 [Marc C. Brooks] 46 /// * better handling of exceptions [Marc C. Brooks] 47 /// * reorganize code, add XML doc and regions [Marc C. Brooks] 48 /// * proper implementations of Equals [Marc C. Brooks, Jeffery Sax] 49 /// * uses Math.Log(xx,2) and Math.Pow(xx,2) to get the best accuracy possible when converting doubles [Marc C. Brooks, Jeffery Sax] 50 /// 51 /// What's new in version 2.3 - Marc C. Brooks mailto:IDisposable@gmail.com 01/10/2005 52 /// * fixed double-to-fraction logic to use continued fraction rules to get best possible precistion [bug fix for Syed Mehroz Alam, idea from Jeffery Sax] 53 /// * added static readonly values for NaN, PositiveInfinity, NegativeInfinity [idea from Jeffery Sax] 54 /// * moved comparisons into an implementation of IComparer [idea from Jeffery Sax] 55 /// * no longer throws for NaN(s) involved in Add, Subtract, Multiply, Divide operations [idea from Jeffery Sax] 56 /// * added static readonly values for Zero, MinValue, MaxValue, Epsilon to better mirror double 57 /// * added IsInfinity to better mirror double. 58 /// * added Modulus and % operators 59 /// 60 /// Properties: 61 /// Numerator: Set/Get value for Numerator 62 /// Denominator: Set/Get value for Numerator 63 /// [Note: If you Set either Property, the Fraction should be passed to ReduceFraction at some point.] 64 /// 65 /// Constructors: 66 /// no arguments: initializes fraction as 0/0 = NaN, so don't do that! 67 /// (Numerator, Denominator): initializes fraction with the given numerator and denominator 68 /// values and reduces 69 /// (long): initializes fraction with the given long value 70 /// (double): initializes fraction with the given double value 71 /// (string): initializes fraction with the given string value 72 /// the string can be an in the form of and integer, double or fraction. 73 /// e.g it can be like "123" or "123.321" or "123/456" 74 /// 75 /// Public Methods (Description is given with respective methods' definitions) 76 /// Fraction ToFraction(long) 77 /// Fraction ToFraction(double) 78 /// Fraction ToFraction(string) 79 /// Int32 ToInt32() 80 /// Int64 ToInt64() 81 /// double ToDouble() 82 /// (override) string ToString() 83 /// Fraction Inverse() 84 /// Fraction Inverted(long) 85 /// Fraction Inverted(double) 86 /// ReduceFraction(ref Fraction) 87 /// CrossReducePair(ref Fraction, ref Fraction) 88 /// (override) Equals(object) 89 /// (override) GetHashCode() 90 /// 91 /// Overloaded Operators (overloaded for Fractions, long and double) 92 /// Unary: - 93 /// Binary: +,-,*,/ 94 /// Relational and Logical Operators: ==,!=,<,>,<=,>= (only == and != for long and doubles) 95 /// 96 /// Overloaded user-defined conversions 97 /// Implicit: From long/double/string to Fraction 98 /// Explicit: From Fraction to long/double/string 99 /// </summary> 100 [Serializable, StructLayout(LayoutKind.Sequential)] 101 public struct Fraction : IComparable, IFormattable 102 { 103 #region Constructors 104 /// <summary> 105 /// Construct a Fraction from an integral value 106 /// </summary> 107 /// <param name="wholeNumber">The value (eventual numerator)</param> 108 /// <remarks>The denominator will be 1</remarks> 109 public Fraction(long wholeNumber) 110 { 111 if (wholeNumber == long.MinValue) 112 wholeNumber++; // prevent serious issues later.. 113 114 m_Numerator = wholeNumber; 115 m_Denominator = 1; 116 // no reducing required, we're a whole number 117 } 118 119 /// <summary> 120 /// Construct a Fraction from a floating-point value 121 /// </summary> 122 /// <param name="floatingPointNumber">The value</param> 123 public Fraction(double floatingPointNumber) 124 { 125 this = ToFraction(floatingPointNumber); 126 } 127 128 /// <summary> 129 /// Construct a Fraction from a string in any legal format 130 /// </summary> 131 /// <param name="inValue">A string with a legal fraction input format</param> 132 /// <remarks>Will reduce the fraction to smallest possible denominator</remarks> 133 /// <see>ToFraction(string strValue)</see> 134 public Fraction(string inValue) 135 { 136 this = ToFraction(inValue); 137 } 138 139 /// <summary> 140 /// Construct a Fraction from a numerator, denominator pair 141 /// </summary> 142 /// <param name="numerator">The numerator (top number)</param> 143 /// <param name="denominator">The denominator (bottom number)</param> 144 /// <remarks>Will reduce the fraction to smallest possible denominator</remarks> 145 public Fraction(long numerator, long denominator) 146 { 147 if (numerator == long.MinValue) 148 numerator++; // prevent serious issues later.. 149 150 if (denominator == long.MinValue) 151 denominator++; // prevent serious issues later.. 152 153 m_Numerator = numerator; 154 m_Denominator = denominator; 155 ReduceFraction(ref this); 156 } 157 158 /// <summary> 159 /// Private constructor to synthesize a Fraction for indeterminates (NaN and infinites) 160 /// </summary> 161 /// <param name="type">Kind of inderterminate</param> 162 private Fraction(Indeterminates type) 163 { 164 m_Numerator = (long)type; 165 m_Denominator = 0; 166 // do NOT reduce, we're clean as can be! 167 } 168 #endregion 169 170 #region Properties 171 /// <summary> 172 /// The 'top' part of the fraction 173 /// </summary> 174 /// <example>For 3/4ths, this is the 3</example> 175 public long Numerator 176 { 177 get 178 { 179 return m_Numerator; 180 } 181 set 182 { 183 m_Numerator = value; 184 } 185 } 186 187 /// <summary> 188 /// The 'bottom' part of the fraction 189 /// </summary> 190 /// <example>For 3/4ths, this is the 4</example> 191 public long Denominator 192 { 193 get 194 { 195 return m_Denominator; 196 } 197 set 198 { 199 m_Denominator = value; 200 } 201 } 202 #endregion 203 204 #region Expose constants 205 public static readonly Fraction NaN = new Fraction(Indeterminates.NaN); 206 public static readonly Fraction PositiveInfinity = new Fraction(Indeterminates.PositiveInfinity); 207 public static readonly Fraction NegativeInfinity = new Fraction(Indeterminates.NegativeInfinity); 208 public static readonly Fraction Zero = new Fraction(0,1); 209 public static readonly Fraction Epsilon = new Fraction(1, Int64.MaxValue); 210 private static readonly double EpsilonDouble = 1.0 / Int64.MaxValue; 211 public static readonly Fraction MaxValue = new Fraction(Int64.MaxValue, 1); 212 public static readonly Fraction MinValue = new Fraction(Int64.MinValue, 1); 213 #endregion 214 215 #region Explicit conversions 216 #region To primitives 217 /// <summary> 218 /// Get the integral value of the Fraction object as int/Int32 219 /// </summary> 220 /// <returns>The (approximate) integer value</returns> 221 /// <remarks>If the value is not a true integer, the fractional part is discarded 222 /// (truncated toward zero). If the valid exceeds the range of an Int32 and exception is thrown.</remarks> 223 /// <exception cref="FractionException">Will throw a FractionException for NaN, PositiveInfinity 224 /// or NegativeInfinity with the InnerException set to a System.NotFiniteNumberException.</exception> 225 /// <exception cref="OverflowException" Will throw a System.OverflowException if the value is too 226 /// large or small to be represented as an Int32.</exception> 227 public Int32 ToInt32() 228 { 229 if (this.m_Denominator == 0) 230 { 231 throw new FractionException(string.Format("Cannot convert {0} to Int32", IndeterminateTypeName(this.m_Numerator)), new System.NotFiniteNumberException()); 232 } 233 234 long bestGuess = this.m_Numerator / this.m_Denominator; 235 236 if (bestGuess > Int32.MaxValue || bestGuess < Int32.MinValue) 237 { 238 throw new FractionException("Cannot convert to Int32", new System.OverflowException()); 239 } 240 241 return (Int32)bestGuess; 242 } 243 244 /// <summary> 245 /// Get the integral value of the Fraction object as long/Int64 246 /// </summary> 247 /// <returns>The (approximate) integer value</returns> 248 /// <remarks>If the value is not a true integer, the fractional part is discarded 249 /// (truncated toward zero). If the valid exceeds the range of an Int32, no special 250 /// handling is guaranteed.</remarks> 251 /// <exception cref="FractionException">Will throw a FractionException for NaN, PositiveInfinity 252 /// or NegativeInfinity with the InnerException set to a System.NotFiniteNumberException.</exception> 253 public Int64 ToInt64() 254 { 255 if (this.m_Denominator == 0) 256 { 257 throw new FractionException(string.Format("Cannot convert {0} to Int64", IndeterminateTypeName(this.m_Numerator)), new System.NotFiniteNumberException()); 258 } 259 260 return this.m_Numerator / this.m_Denominator; 261 } 262 263 /// <summary> 264 /// Get the value of the Fraction object as double with full support for NaNs and infinities 265 /// </summary> 266 /// <returns>The decimal representation of the Fraction, or double.NaN, double.NegativeInfinity 267 /// or double.PositiveInfinity</returns> 268 public double ToDouble() 269 { 270 if (this.m_Denominator == 1) 271 return this.m_Numerator; 272 else if (this.m_Denominator == 0) 273 { 274 switch (NormalizeIndeterminate(this.m_Numerator)) 275 { 276 case Indeterminates.NegativeInfinity: 277 return double.NegativeInfinity; 278 279 case Indeterminates.PositiveInfinity: 280 return double.PositiveInfinity; 281 282 case Indeterminates.NaN: 283 default: // this can't happen 284 return double.NaN; 285 } 286 } 287 else 288 { 289 return (double)this.m_Numerator / (double)this.m_Denominator; 290 } 291 } 292 293 /// <summary> 294 /// Get the value of the Fraction as a string, with proper representation for NaNs and infinites 295 /// </summary> 296 /// <returns>The string representation of the Fraction, or the culture-specific representations of 297 /// NaN, PositiveInfinity or NegativeInfinity.</returns> 298 /// <remarks>The current culture determines the textual representation the Indeterminates</remarks> 299 public override string ToString() 300 { 301 if (this.m_Denominator == 1) 302 { 303 return this.m_Numerator.ToString(); 304 } 305 else if (this.m_Denominator == 0) 306 { 307 return IndeterminateTypeName(this.m_Numerator); 308 } 309 else 310 { 311 return this.m_Numerator.ToString() + "/" + this.m_Denominator.ToString(); 312 } 313 } 314 #endregion 315 316 #region From primitives 317 /// <summary> 318 /// Converts a long value to the exact Fraction 319 /// </summary> 320 /// <param name="inValue">The long to convert</param> 321 /// <returns>An exact representation of the value</returns> 322 public static Fraction ToFraction(long inValue) 323 { 324 return new Fraction(inValue); 325 } 326 327 /// <summary> 328 /// Converts a double value to the approximate Fraction 329 /// </summary> 330 /// <param name="inValue">The double to convert</param> 331 /// <returns>A best-fit representation of the value</returns> 332 /// <remarks>Supports double.NaN, double.PositiveInfinity and double.NegativeInfinity</remarks> 333 public static Fraction ToFraction(double inValue) 334 { 335 // it's one of the indeterminates... which? 336 if (double.IsNaN(inValue)) 337 return NaN; 338 else if (double.IsNegativeInfinity(inValue)) 339 return NegativeInfinity; 340 else if (double.IsPositiveInfinity(inValue)) 341 return PositiveInfinity; 342 else if (inValue == 0.0d) 343 return Zero; 344 345 if (inValue > Int64.MaxValue) 346 throw new OverflowException(string.Format("Double {0} too large", inValue)); 347 348 if (inValue < -Int64.MaxValue) 349 throw new OverflowException(string.Format("Double {0} too small", inValue)); 350 351 if (-EpsilonDouble < inValue && inValue < EpsilonDouble) 352 throw new ArithmeticException(string.Format("Double {0} cannot be represented", inValue)); 353 354 int sign = Math.Sign(inValue); 355 inValue = Math.Abs(inValue); 356 357 return ConvertPositiveDouble(sign, inValue); 358 } 359 360 /// <summary> 361 /// Converts a string to the corresponding reduced fraction 362 /// </summary> 363 /// <param name="inValue">The string representation of a fractional value</param> 364 /// <returns>The Fraction that represents the string</returns> 365 /// <remarks>Four forms are supported, as a plain integer, as a double, or as Numerator/Denominator 366 /// and the representations for NaN and the infinites</remarks> 367 /// <example>"123" = 123/1 and "1.25" = 5/4 and "10/36" = 5/13 and NaN = 0/0 and 368 /// PositiveInfinity = 1/0 and NegativeInfinity = -1/0</example> 369 public static Fraction ToFraction(string inValue) 370 { 371 if (inValue == null || inValue == string.Empty) 372 throw new ArgumentNullException("inValue"); 373 374 // could also be NumberFormatInfo.InvariantInfo 375 NumberFormatInfo info = NumberFormatInfo.CurrentInfo; 376 377 // Is it one of the special symbols for NaN and such... 378 string trimmedValue = inValue.Trim(); 379 380 if (trimmedValue == info.NaNSymbol) 381 return NaN; 382 else if (trimmedValue == info.PositiveInfinitySymbol) 383 return PositiveInfinity; 384 else if (trimmedValue == info.NegativeInfinitySymbol) 385 return NegativeInfinity; 386 else 387 { 388 // Not special, is it a Fraction? 389 int slashPos = inValue.IndexOf('/'); 390 391 if (slashPos > -1) 392 { 393 // string is in the form of Numerator/Denominator 394 long numerator = Convert.ToInt64(inValue.Substring(0, slashPos)); 395 long denominator = Convert.ToInt64(inValue.Substring(slashPos + 1)); 396 397 return new Fraction(numerator, denominator); 398 } 399 else 400 { 401 // the string is not in the form of a fraction 402 // hopefully it is double or integer, do we see a decimal point? 403 int decimalPos = inValue.IndexOf(info.CurrencyDecimalSeparator); 404 405 if (decimalPos > -1) 406 return new Fraction(Convert.ToDouble(inValue)); 407 else 408 return new Fraction(Convert.ToInt64(inValue)); 409 } 410 } 411 } 412 #endregion 413 #endregion 414 415 #region Indeterminate classifications 416 /// <summary> 417 /// Determines if a Fraction represents a Not-a-Number 418 /// </summary> 419 /// <returns>True if the Fraction is a NaN</returns> 420 public bool IsNaN() 421 { 422 if (this.m_Denominator == 0 423 && NormalizeIndeterminate(this.m_Numerator) == Indeterminates.NaN) 424 return true; 425 else 426 return false; 427 } 428 429 /// <summary> 430 /// Determines if a Fraction represents Any Infinity 431 /// </summary> 432 /// <returns>True if the Fraction is Positive Infinity or Negative Infinity</returns> 433 public bool IsInfinity() 434 { 435 if (this.m_Denominator == 0 436 && NormalizeIndeterminate(this.m_Numerator) != Indeterminates.NaN) 437 return true; 438 else 439 return false; 440 } 441 442 /// <summary> 443 /// Determines if a Fraction represents Positive Infinity 444 /// </summary> 445 /// <returns>True if the Fraction is Positive Infinity</returns> 446 public bool IsPositiveInfinity() 447 { 448 if (this.m_Denominator == 0 449 && NormalizeIndeterminate(this.m_Numerator) == Indeterminates.PositiveInfinity) 450 return true; 451 else 452 return false; 453 } 454 455 /// <summary> 456 /// Determines if a Fraction represents Negative Infinity 457 /// </summary> 458 /// <returns>True if the Fraction is Negative Infinity</returns> 459 public bool IsNegativeInfinity() 460 { 461 if (this.m_Denominator == 0 462 && NormalizeIndeterminate(this.m_Numerator) == Indeterminates.NegativeInfinity) 463 return true; 464 else 465 return false; 466 } 467 #endregion 468 469 #region Inversion 470 /// <summary> 471 /// Inverts a Fraction 472 /// </summary> 473 /// <returns>The inverted Fraction (with Denominator over Numerator)</returns> 474 /// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks> 475 public Fraction Inverse() 476 { 477 // don't use the obvious constructor because we do not want it normalized at this time 478 Fraction frac = new Fraction(); 479 480 frac.m_Numerator = this.m_Denominator; 481 frac.m_Denominator = this.m_Numerator; 482 return frac; 483 } 484 485 /// <summary> 486 /// Creates an inverted Fraction 487 /// </summary> 488 /// <returns>The inverted Fraction (with Denominator over Numerator)</returns> 489 /// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks> 490 public static Fraction Inverted(long value) 491 { 492 Fraction frac = new Fraction(value); 493 return frac.Inverse(); 494 } 495 496 /// <summary> 497 /// Creates an inverted Fraction 498 /// </summary> 499 /// <returns>The inverted Fraction (with Denominator over Numerator)</returns> 500 /// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks> 501 public static Fraction Inverted(double value) 502 { 503 Fraction frac = new Fraction(value); 504 return frac.Inverse(); 505 } 506 #endregion 507 508 #region Operators 509 #region Unary Negation operator 510 /// <summary> 511 /// Negates the Fraction 512 /// </summary> 513 /// <param name="left">The Fraction to negate</param> 514 /// <returns>The negative version of the Fraction</returns> 515 public static Fraction operator -(Fraction left) 516 { 517 return Negate(left); 518 } 519 #endregion 520 521 #region Addition operators 522 public static Fraction operator +(Fraction left, Fraction right) 523 { 524 return Add(left, right); 525 } 526 527 public static Fraction operator +(long left, Fraction right) 528 { 529 return Add(new Fraction(left), right); 530 } 531 532 public static Fraction operator +(Fraction left, long right) 533 { 534 return Add(left, new Fraction(right)); 535 } 536 537 public static Fraction operator +(double left, Fraction right) 538 { 539 return Add(ToFraction(left), right); 540 } 541 542 public static Fraction operator +(Fraction left, double right) 543 { 544 return Add(left, ToFraction(right)); 545 } 546 #endregion 547 548 #region Subtraction operators 549 public static Fraction operator -(Fraction left, Fraction right) 550 { 551 return Add(left, - right); 552 } 553 554 public static Fraction operator -(long left, Fraction right) 555 { 556 return Add(new Fraction(left), - right); 557 } 558 559 public static Fraction operator -(Fraction left, long right) 560 { 561 return Add(left, new Fraction(- right)); 562 } 563 564 public static Fraction operator -(double left, Fraction right) 565 { 566 return Add(ToFraction(left), - right); 567 } 568 569 public static Fraction operator -(Fraction left, double right) 570 { 571 return Add(left, ToFraction(- right)); 572 } 573 #endregion 574 575 #region Multiplication operators 576 public static Fraction operator *(Fraction left, Fraction right) 577 { 578 return Multiply(left, right); 579 } 580 581 public static Fraction operator *(long left, Fraction right) 582 { 583 return Multiply(new Fraction(left), right); 584 } 585 586 public static Fraction operator *(Fraction left, long right) 587 { 588 return Multiply(left, new Fraction(right)); 589 } 590 591 public static Fraction operator *(double left, Fraction right) 592 { 593 return Multiply(ToFraction(left), right); 594 } 595 596 public static Fraction operator *(Fraction left, double right) 597 { 598 return Multiply(left, ToFraction(right)); 599 } 600 #endregion 601 602 #region Division operators 603 public static Fraction operator /(Fraction left, Fraction right) 604 { 605 return Multiply(left, right.Inverse()); 606 } 607 608 public static Fraction operator /(long left, Fraction right) 609 { 610 return Multiply(new Fraction(left), right.Inverse()); 611 } 612 613 public static Fraction operator /(Fraction left, long right) 614 { 615 return Multiply(left, Inverted(right)); 616 } 617 618 public static Fraction operator /(double left, Fraction right) 619 { 620 return Multiply(ToFraction(left), right.Inverse()); 621 } 622 623 public static Fraction operator /(Fraction left, double right) 624 { 625 return Multiply(left, Inverted(right)); 626 } 627 #endregion 628 629 #region Modulus operators 630 public static Fraction operator %(Fraction left, Fraction right) 631 { 632 return Modulus(left, right); 633 } 634 635 public static Fraction operator %(long left, Fraction right) 636 { 637 return Modulus(new Fraction(left), right); 638 } 639 640 public static Fraction operator %(Fraction left, long right) 641 { 642 return Modulus(left, right); 643 } 644 645 public static Fraction operator %(double left, Fraction right) 646 { 647 return Modulus(ToFraction(left), right); 648 } 649 650 public static Fraction operator %(Fraction left, double right) 651 { 652 return Modulus(left, right); 653 } 654 #endregion 655 656 #region Equal operators 657 public static bool operator ==(Fraction left, Fraction right) 658 { 659 return left.CompareEquality(right, false); 660 } 661 662 public static bool operator ==(Fraction left, long right) 663 { 664 return left.CompareEquality(new Fraction(right), false); 665 } 666 667 public static bool operator ==(Fraction left, double right) 668 { 669 return left.CompareEquality(new Fraction(right), false); 670 } 671 #endregion 672 673 #region Not-equal operators 674 public static bool operator !=(Fraction left, Fraction right) 675 { 676 return left.CompareEquality(right, true); 677 } 678 679 public static bool operator !=(Fraction left, long right) 680 { 681 return left.CompareEquality(new Fraction(right), true); 682 } 683 684 public static bool operator !=(Fraction left, double right) 685 { 686 return left.CompareEquality(new Fraction(right), true); 687 } 688 #endregion 689 690 #region Inequality operators 691 /// <summary> 692 /// Compares two Fractions to see if left is less than right 693 /// </summary> 694 /// <param name="left">The first Fraction</param> 695 /// <param name="right">The second Fraction</param> 696 /// <returns>True if <paramref name="left">left</paramref> is less 697 /// than <paramref name="right">right</paramref></returns> 698 /// <remarks>Special handling for indeterminates exists. <see>IndeterminateLess</see></remarks> 699 /// <exception cref="FractionException">Throws an error if overflows occur while computing the 700 /// difference with an InnerException of OverflowException</exception> 701 public static bool operator <(Fraction left, Fraction right) 702 { 703 return left.CompareTo(right) < 0; 704 } 705 706 /// <summary> 707 /// Compares two Fractions to see if left is greater than right 708 /// </summary> 709 /// <param name="left">The first Fraction</param> 710 /// <param name="right">The second Fraction</param> 711 /// <returns>True if <paramref name="left">left</paramref> is greater 712 /// than <paramref name="right">right</paramref></returns> 713 /// <remarks>Special handling for indeterminates exists. <see>IndeterminateLess</see></remarks> 714 /// <exception cref="FractionException">Throws an error if overflows occur while computing the 715 /// difference with an InnerException of OverflowException</exception> 716 public static bool operator >(Fraction left, Fraction right) 717 { 718 return left.CompareTo(right) > 0; 719 } 720 721 /// <summary> 722 /// Compares two Fractions to see if left is less than or equal to right 723 /// </summary> 724 /// <param name="left">The first Fraction</param> 725 /// <param name="right">The second Fraction</param> 726 /// <returns>True if <paramref name="left">left</paramref> is less than or 727 /// equal to <paramref name="right">right</paramref></returns> 728 /// <remarks>Special handling for indeterminates exists. <see>IndeterminateLessEqual</see></remarks> 729 /// <exception cref="FractionException">Throws an error if overflows occur while computing the 730 /// difference with an InnerException of OverflowException</exception> 731 public static bool operator <=(Fraction left, Fraction right) 732 { 733 return left.CompareTo(right) <= 0; 734 } 735 736 /// <summary> 737 /// Compares two Fractions to see if left is greater than or equal to right 738 /// </summary> 739 /// <param name="left">The first Fraction</param> 740 /// <param name="right">The second Fraction</param> 741 /// <returns>True if <paramref name="left">left</paramref> is greater than or 742 /// equal to <paramref name="right">right</paramref></returns> 743 /// <remarks>Special handling for indeterminates exists. <see>IndeterminateLessEqual</see></remarks> 744 /// <exception cref="FractionException">Throws an error if overflows occur while computing the 745 /// difference with an InnerException of OverflowException</exception> 746 public static bool operator >=(Fraction left, Fraction right) 747 { 748 return left.CompareTo(right) >= 0; 749 } 750 #endregion 751 752 #region Implict conversion from primitive operators 753 /// <summary> 754 /// Implicit conversion of a long integral value to a Fraction 755 /// </summary> 756 /// <param name="value">The long integral value to convert</param> 757 /// <returns>A Fraction whose denominator is 1</returns> 758 public static implicit operator Fraction(long value) 759 { 760 return new Fraction(value); 761 } 762 763 /// <summary> 764 /// Implicit conversion of a double floating point value to a Fraction 765 /// </summary> 766 /// <param name="value">The double value to convert</param> 767 /// <returns>A reduced Fraction</returns> 768 public static implicit operator Fraction(double value) 769 { 770 return new Fraction(value); 771 } 772 773 /// <summary> 774 /// Implicit conversion of a string to a Fraction 775 /// </summary> 776 /// <param name="value">The string to convert</param> 777 /// <returns>A reduced Fraction</returns> 778 public static implicit operator Fraction(string value) 779 { 780 return new Fraction(value); 781 } 782 #endregion 783 784 #region Explicit converstion to primitive operators 785 /// <summary> 786 /// Explicit conversion from a Fraction to an integer 787 /// </summary> 788 /// <param name="frac">the Fraction to convert</param> 789 /// <returns>The integral representation of the Fraction</returns> 790 public static explicit operator int(Fraction frac) 791 { 792 return frac.ToInt32(); 793 } 794 795 /// <summary> 796 /// Explicit conversion from a Fraction to an integer 797 /// </summary> 798 /// <param name="frac">The Fraction to convert</param> 799 /// <returns>The integral representation of the Fraction</returns> 800 public static explicit operator long(Fraction frac) 801 { 802 return frac.ToInt64(); 803 } 804 805 /// <summary> 806 /// Explicit conversion from a Fraction to a double floating-point value 807 /// </summary> 808 /// <param name="frac">The Fraction to convert</param> 809 /// <returns>The double representation of the Fraction</returns> 810 public static explicit operator double(Fraction frac) 811 { 812 return frac.ToDouble(); 813 } 814 815 /// <summary> 816 /// Explicit conversion from a Fraction to a string 817 /// </summary> 818 /// <param name="frac">the Fraction to convert</param> 819 /// <returns>The string representation of the Fraction</returns> 820 public static implicit operator string(Fraction frac) 821 { 822 return frac.ToString(); 823 } 824 #endregion 825 #endregion 826 827 #region Equals and GetHashCode overrides 828 /// <summary> 829 /// Compares for equality the current Fraction to the value passed. 830 /// </summary> 831 /// <param name="obj">A Fraction,</param> 832 /// <returns>True if the value equals the current fraction, false otherwise (including for 833 /// non-Fraction types or null object.</returns> 834 public override bool Equals(object obj) 835 { 836 if (obj == null || ! (obj is Fraction)) 837 return false; 838 839 try 840 { 841 Fraction right = (Fraction)obj; 842 return this.CompareEquality(right, false); 843 } 844 catch 845 { 846 // can't throw in an Equals! 847 return false; 848 } 849 } 850 851 /// <summary> 852 /// Returns a hash code generated from the current Fraction 853 /// </summary> 854 /// <returns>The hash code</returns> 855 /// <remarks>Reduces (in-place) the Fraction first.</remarks> 856 public override int GetHashCode() 857 { 858 // insure we're as close to normalized as possible first 859 ReduceFraction(ref this); 860 861 int numeratorHash = this.m_Numerator.GetHashCode(); 862 int denominatorHash = this.m_Denominator.GetHashCode(); 863 864 return (numeratorHash ^ denominatorHash); 865 } 866 #endregion 867 868 #region IComparable member and type-specific version 869 /// <summary> 870 /// Compares an object to this Fraction 871 /// </summary> 872 /// <param name="obj">The object to compare against (null is less than everything)</param> 873 /// <returns>-1 if this is less than <paramref name="obj"></paramref>, 874 /// 0 if they are equal, 875 /// 1 if this is greater than <paramref name="obj"></paramref></returns> 876 /// <remarks>Will convert an object from longs, doubles, and strings as this is a value-type.</remarks> 877 public int CompareTo(object obj) 878 { 879 if (obj == null) 880 return 1; // null is less than anything 881 882 Fraction right; 883 884 if (obj is Fraction) 885 right = (Fraction)obj; 886 else if (obj is long) 887 right = (long)obj; 888 else if (obj is double) 889 right = (double)obj; 890 else if (obj is string) 891 right = (string)obj; 892 else 893 throw new ArgumentException("Must be convertible to Fraction", "obj"); 894 895 return this.CompareTo(right); 896 } 897 898 /// <summary> 899 /// Compares this Fraction to another Fraction 900 /// </summary> 901 /// <param name="right">The Fraction to compare against</param> 902 /// <returns>-1 if this is less than <paramref name="right"></paramref>, 903 /// 0 if they are equal, 904 /// 1 if this is greater than <paramref name="right"></paramref></returns> 905 public int CompareTo(Fraction right) 906 { 907 // if left is an indeterminate, punt to the helper... 908 if (this.m_Denominator == 0) 909 { 910 return IndeterminantCompare(NormalizeIndeterminate(this.m_Numerator), right); 911 } 912 913 // if right is an indeterminate, punt to the helper... 914 if (right.m_Denominator == 0) 915 { 916 // note sign-flip... 917 return - IndeterminantCompare(NormalizeIndeterminate(right.m_Numerator), this); 918 } 919 920 // they're both normal Fractions 921 CrossReducePair(ref this, ref right); 922 923 try 924 { 925 checked 926 { 927 long leftScale = this.m_Numerator * right.m_Denominator; 928 long rightScale = this.m_Denominator * right.m_Numerator; 929 930 if (leftScale < rightScale) 931 return -1; 932 else if (leftScale > rightScale) 933 return 1; 934 else 935 return 0; 936 } 937 } 938 catch (Exception e) 939 { 940 throw new FractionException(string.Format("CompareTo({0}, {1}) error", this, right), e); 941 } 942 } 943 #endregion 944 945 #region IFormattable Members 946 string System.IFormattable.ToString(string format, IFormatProvider formatProvider) 947 { 948 return this.m_Numerator.ToString(format, formatProvider) + "/" + this.m_Denominator.ToString(format, formatProvider); 949 } 950 #endregion 951 952 #region Reduction 953 /// <summary> 954 /// Reduces (simplifies) a Fraction by dividing down to lowest possible denominator (via GCD) 955 /// </summary> 956 /// <param name="frac">The Fraction to be reduced [WILL BE MODIFIED IN PLACE]</param> 957 /// <remarks>Modifies the input arguments in-place! Will normalize the NaN and infinites 958 /// representation. Will set Denominator to 1 for any zero numerator. Moves sign to the 959 /// Numerator.</remarks> 960 /// <example>2/4 will be reduced to 1/2</example> 961 public static void ReduceFraction(ref Fraction frac) 962 { 963 // clean up the NaNs and infinites 964 if (frac.m_Denominator == 0) 965 { 966 frac.m_Numerator = (long)NormalizeIndeterminate(frac.m_Numerator); 967 return; 968 } 969 970 // all forms of zero are alike. 971 if (frac.m_Numerator == 0) 972 { 973 frac.m_Denominator = 1; 974 return; 975 } 976 977 long iGCD = GCD(frac.m_Numerator, frac.m_Denominator); 978 frac.m_Numerator /= iGCD; 979 frac.m_Denominator /= iGCD; 980 981 // if negative sign in denominator 982 if ( frac.m_Denominator < 0 ) 983 { 984 //move negative sign to numerator 985 frac.m_Numerator = - frac.m_Numerator; 986 frac.m_Denominator = - frac.m_Denominator; 987 } 988 } 989 990 /// <summary> 991 /// Cross-reduces a pair of Fractions so that we have the best GCD-reduced values for multiplication 992 /// </summary> 993 /// <param name="frac1">The first Fraction [WILL BE MODIFIED IN PLACE]</param> 994 /// <param name="frac2">The second Fraction [WILL BE MODIFIED IN PLACE]</param> 995 /// <remarks>Modifies the input arguments in-place!</remarks> 996 /// <example>(3/4, 5/9) = (1/4, 5/3)</example> 997 public static void CrossReducePair(ref Fraction frac1, ref Fraction frac2) 998 { 999 // leave the indeterminates alone! 1000 if (frac1.m_Denominator == 0 || frac2.m_Denominator == 0) 1001 return; 1002 1003 long gcdTop = GCD(frac1.m_Numerator, frac2.m_Denominator); 1004 frac1.m_Numerator = frac1.m_Numerator / gcdTop; 1005 frac2.m_Denominator = frac2.m_Denominator / gcdTop; 1006 1007 long gcdBottom = GCD(frac1.m_Denominator, frac2.m_Numerator); 1008 frac2.m_Numerator = frac2.m_Numerator / gcdBottom; 1009 frac1.m_Denominator = frac1.m_Denominator / gcdBottom; 1010 } 1011 #endregion 1012 1013 #region Implementation 1014 #region Convert a double to a fraction 1015 private static Fraction ConvertPositiveDouble(int sign, double inValue) 1016 { 1017 // Shamelessly stolen from http://homepage.smc.edu/kennedy_john/CONFRAC.PDF 1018 // with AccuracyFactor == double.Episilon 1019 long fractionNumerator = (long)inValue; 1020 double fractionDenominator = 1; 1021 double previousDenominator = 0; 1022 double remainingDigits = inValue; 1023 int maxIterations = 594; // found at http://www.ozgrid.com/forum/archive/index.php/t-22530.html 1024 1025 while (remainingDigits != Math.Floor(remainingDigits) 1026 && Math.Abs(inValue - (fractionNumerator / fractionDenominator)) > double.Epsilon) 1027 { 1028 remainingDigits = 1.0 / (remainingDigits - Math.Floor(remainingDigits)); 1029 1030 double scratch = fractionDenominator; 1031 1032 fractionDenominator =(Math.Floor(remainingDigits) * fractionDenominator) + previousDenominator; 1033 fractionNumerator = (long)(inValue * fractionDenominator + 0.5); 1034 1035 previousDenominator = scratch; 1036 1037 if (maxIterations-- < 0) 1038 break; 1039 } 1040 1041 return new Fraction(fractionNumerator * sign, (long)fractionDenominator); 1042 } 1043 #endregion 1044 1045 #region Equality helper 1046 /// <summary> 1047 /// Compares for equality the current Fraction to the value passed. 1048 /// </summary> 1049 /// <param name="right">A Fraction to compare against</param> 1050 /// <param name="notEqualCheck">If true, we're looking for not-equal</param> 1051 /// <returns>True if the <paramref name="right"></paramref> equals the current 1052 /// fraction, false otherwise. If comparing two NaNs, they are always equal AND 1053 /// not-equal.</returns> 1054 private bool CompareEquality(Fraction right, bool notEqualCheck) 1055 { 1056 // insure we're normalized first 1057 ReduceFraction(ref this); 1058 1059 // now normalize the comperand 1060 ReduceFraction(ref right); 1061 1062 if (this.m_Numerator == right.m_Numerator && this.m_Denominator == right.m_Denominator) 1063 { 1064 // special-case rule, two NaNs are always both equal 1065 if (notEqualCheck && this.IsNaN()) 1066 return true; 1067 else 1068 return ! notEqualCheck; 1069 } 1070 else 1071 { 1072 return notEqualCheck; 1073 } 1074 } 1075 #endregion 1076 1077 #region Comparison helper 1078 /// <summary> 1079 /// Determines how this Fraction, of an indeterminate type, compares to another Fraction 1080 /// </summary> 1081 /// <param name="leftType">What kind of indeterminate</param> 1082 /// <param name="right">The other Fraction to compare against</param> 1083 /// <returns>-1 if this is less than <paramref name="right"></paramref>, 1084 /// 0 if they are equal, 1085 /// 1 if this is greater than <paramref name="right"></paramref></returns> 1086 /// <remarks>NaN is less than anything except NaN and Negative Infinity. Negative Infinity is less 1087 /// than anything except Negative Infinity. Positive Infinity is greater than anything except 1088 /// Positive Infinity.</remarks> 1089 private static int IndeterminantCompare(Indeterminates leftType, Fraction right) 1090 { 1091 switch (leftType) 1092 { 1093 case Indeterminates.NaN: 1094 // A NaN is... 1095 if (right.IsNaN()) 1096 return 0; // equal to a NaN 1097 else if (right.IsNegativeInfinity()) 1098 return 1; // great than Negative Infinity 1099 else 1100 return -1; // less than anything else 1101 1102 case Indeterminates.NegativeInfinity: 1103 // Negative Infinity is... 1104 if (right.IsNegativeInfinity()) 1105 return 0; // equal to Negative Infinity 1106 else 1107 return -1; // less than anything else 1108 1109 case Indeterminates.PositiveInfinity: 1110 if (right.IsPositiveInfinity()) 1111 return 0; // equal to Positive Infinity 1112 else 1113 return 1; // greater than anything else 1114 1115 default: 1116 // this CAN'T happen, something VERY wrong is going on... 1117 return 0; 1118 } 1119 } 1120 #endregion 1121 1122 #region Math helpers 1123 /// <summary> 1124 /// Negates the Fraction 1125 /// </summary> 1126 /// <param name="frac">Value to negate</param> 1127 /// <returns>A new Fraction that is sign-flipped from the input</returns> 1128 private static Fraction Negate(Fraction frac) 1129 { 1130 // for a NaN, it's still a NaN 1131 return new Fraction( - frac.m_Numerator, frac.m_Denominator); 1132 } 1133 1134 /// <summary> 1135 /// Adds two Fractions 1136 /// </summary> 1137 /// <param name="left">A Fraction</param> 1138 /// <param name="right">Another Fraction</param> 1139 /// <returns>Sum of the Fractions. Returns NaN if either Fraction is a NaN.</returns> 1140 /// <exception cref="FractionException">Will throw if an overflow occurs when computing the 1141 /// GCD-normalized values.</exception> 1142 private static Fraction Add(Fraction left, Fraction right) 1143 { 1144 if (left.IsNaN() || right.IsNaN()) 1145 return NaN; 1146 1147 long gcd = GCD(left.m_Denominator, right.m_Denominator); // cannot return less than 1 1148 long leftDenominator = left.m_Denominator / gcd; 1149 long rightDenominator = right.m_Denominator / gcd; 1150 1151 try 1152 { 1153 checked 1154 { 1155 long numerator = left.m_Numerator * rightDenominator + right.m_Numerator * leftDenominator; 1156 long denominator = leftDenominator * rightDenominator * gcd; 1157 1158 return new Fraction(numerator, denominator); 1159 } 1160 } 1161 catch (Exception e) 1162 { 1163 throw new FractionException("Add error", e); 1164 } 1165 } 1166 1167 /// <summary> 1168 /// Multiplies two Fractions 1169 /// </summary> 1170 /// <param name="left">A Fraction</param> 1171 /// <param name="right">Another Fraction</param> 1172 /// <returns>Product of the Fractions. Returns NaN if either Fraction is a NaN.</returns> 1173 /// <exception cref="FractionException">Will throw if an overflow occurs. Does a cross-reduce to 1174 /// insure only the unavoidable overflows occur.</exception> 1175 private static Fraction Multiply(Fraction left, Fraction right) 1176 { 1177 if (left.IsNaN() || right.IsNaN()) 1178 return NaN; 1179 1180 // this would be unsafe if we were not a ValueType, because we would be changing the 1181 // caller's values. If we change back to a class, must use temporaries 1182 CrossReducePair(ref left, ref right); 1183 1184 try 1185 { 1186 checked 1187 { 1188 long numerator = left.m_Numerator * right.m_Numerator; 1189 long denominator = left.m_Denominator * right.m_Denominator; 1190 1191 return new Fraction(numerator, denominator); 1192 } 1193 } 1194 catch (Exception e) 1195 { 1196 throw new FractionException("Multiply error", e); 1197 } 1198 } 1199 1200 /// <summary> 1201 /// Returns the modulus (remainder after dividing) two Fractions 1202 /// </summary> 1203 /// <param name="left">A Fraction</param> 1204 /// <param name="right">Another Fraction</param> 1205 /// <returns>Modulus of the Fractions. Returns NaN if either Fraction is a NaN.</returns> 1206 /// <exception cref="FractionException">Will throw if an overflow occurs. Does a cross-reduce to 1207 /// insure only the unavoidable overflows occur.</exception> 1208 private static Fraction Modulus(Fraction left, Fraction right) 1209 { 1210 if (left.IsNaN() || right.IsNaN()) 1211 return NaN; 1212 1213 try 1214 { 1215 checked 1216 { 1217 // this will discard any fractional places... 1218 Int64 quotient = (Int64)(left / right); 1219 Fraction whole = new Fraction(quotient * right.m_Numerator, right.m_Denominator); 1220 return left - whole; 1221 } 1222 } 1223 catch (Exception e) 1224 { 1225 throw new FractionException("Modulus error", e); 1226 } 1227 } 1228 1229 /// <summary> 1230 /// Computes the greatest common divisor for two values 1231 /// </summary> 1232 /// <param name="left">One value</param> 1233 /// <param name="right">Another value</param> 1234 /// <returns>The greatest common divisor of the two values</returns> 1235 /// <example>(6, 9) returns 3 and (11, 4) returns 1</example> 1236 private static long GCD(long left, long right) 1237 { 1238 // take absolute values 1239 if (left < 0) 1240 left = - left; 1241 1242 if (right < 0) 1243 right = - right; 1244 1245 // if we're dealing with any zero or one, the GCD is 1 1246 if (left < 2 || right < 2) 1247 return 1; 1248 1249 do 1250 { 1251 if (left < right) 1252 { 1253 long temp = left; // swap the two operands 1254 left = right; 1255 right = temp; 1256 } 1257 1258 left %= right; 1259 } while (left != 0); 1260 1261 return right; 1262 } 1263 #endregion 1264 1265 #region Indeterminate helpers 1266 /// <summary> 1267 /// Gives the culture-related representation of the indeterminate types NaN, PositiveInfinity 1268 /// and NegativeInfinity 1269 /// </summary> 1270 /// <param name="numerator">The value in the numerator</param> 1271 /// <returns>The culture-specific string representation of the implied value</returns> 1272 /// <remarks>Only the sign and zero/non-zero information is relevant.</remarks> 1273 private static string IndeterminateTypeName(long numerator) 1274 { 1275 // could also be NumberFormatInfo.InvariantInfo 1276 System.Globalization.NumberFormatInfo info = NumberFormatInfo.CurrentInfo; 1277 1278 switch (NormalizeIndeterminate(numerator)) 1279 { 1280 case Indeterminates.PositiveInfinity: 1281 return info.PositiveInfinitySymbol; 1282 1283 case Indeterminates.NegativeInfinity: 1284 return info.NegativeInfinitySymbol; 1285 1286 default: // if this happens, something VERY wrong is going on... 1287 case Indeterminates.NaN: 1288 return info.NaNSymbol; 1289 } 1290 } 1291 1292 /// <summary> 1293 /// Gives the normalize representation of the indeterminate types NaN, PositiveInfinity 1294 /// and NegativeInfinity 1295 /// </summary> 1296 /// <param name="numerator">The value in the numerator</param> 1297 /// <returns>The normalized version of the indeterminate type</returns> 1298 /// <remarks>Only the sign and zero/non-zero information is relevant.</remarks> 1299 private static Indeterminates NormalizeIndeterminate(long numerator) 1300 { 1301 switch (Math.Sign(numerator)) 1302 { 1303 case 1: 1304 return Indeterminates.PositiveInfinity; 1305 1306 case -1: 1307 return Indeterminates.NegativeInfinity; 1308 1309 default: // if this happens, your Math.Sign function is BROKEN! 1310 case 0: 1311 return Indeterminates.NaN; 1312 } 1313 } 1314 1315 // These are used to represent the indeterminate with a Denominator of zero 1316 private enum Indeterminates 1317 { 1318 NaN = 0 1319 , PositiveInfinity = 1 1320 , NegativeInfinity = -1 1321 } 1322 #endregion 1323 1324 #region Member variables 1325 private long m_Numerator; 1326 private long m_Denominator; 1327 #endregion 1328 #endregion 1329 } //end class Fraction 1330 1331 /// <summary> 1332 /// Exception class for Fraction, derived from System.Exception 1333 /// </summary> 1334 public class FractionException : Exception 1335 { 1336 /// <summary> 1337 /// Constructs a FractionException 1338 /// </summary> 1339 /// <param name="Message">String associated with the error message</param> 1340 /// <param name="InnerException">Actual inner exception caught</param> 1341 public FractionException(string Message, Exception InnerException) : base(Message, InnerException) 1342 { 1343 } 1344 } //end class FractionException 1345 } //end namespace Mehroz 1 /* 2 * Author: Syed Mehroz Alam 3 * Email: smehrozalam@yahoo.com 4 * URL: Programming Home "http://www.geocities.com/smehrozalam/" 5 * 6 */ 7 8 using System; 9 using System.Globalization; 10 using System.Runtime.InteropServices; 11 12 namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers { 13 /// <summary> 14 /// Classes Contained: 15 /// Fraction 16 /// FractionException 17 /// </summary> 18 19 /// Class name: Fraction 20 /// Developed by: Syed Mehroz Alam 21 /// Email: mailto:smehrozalam@yahoo.com 22 /// URL: http://www.geocities.com/smehrozalam/ 23 /// Changes: Marc C. Brooks mailto:IDisposable@gmail.com 24 /// Jeffery Sax http://www.extremeoptimization.com 25 /// Version: 2.2 26 /// 27 /// What's new in version 2.0: 28 /// * Changed Numerator and Denominator from Int32(integer) to Int64(long) for increased range 29 /// * renamed ConvertToString() to (overloaded) ToString() 30 /// * added the capability of detecting/raising overflow exceptions 31 /// * Fixed the bug that very small numbers e.g. 0.00000001 could not be converted to fraction 32 /// * Other minor bugs fixed 33 /// 34 /// What's new in version 2.1 35 /// * overloaded user-defined conversions to/from Fractions 36 /// 37 /// What's new in version 2.2 - Marc C. Brooks mailto:IDisposable@gmail.com 38 /// * less overflows by finding the GCD for Add [Jeffery Sax] and Multiply [Marc C. Brooks] 39 /// * understands and handles NaN, PositiveInfinity, NegativeInfinity just like double [Marc C. Brooks] 40 /// * fixed several uses of int where long was correct [Marc C. Brooks] 41 /// * made value-type (struct) [Jeffery Sax] 42 /// * added ToInt32(), ToInt64() which throw for invalid (NaN, PositiveInfinity, NegativeInfinity) [Marc C. Brooks] 43 /// * removed redundant Value property [Jeffery Sax] 44 /// * added explicit conversion to Int32 and Int64 [Marc C. Brooks] 45 /// * better handling of exceptions [Marc C. Brooks] 46 /// * reorganize code, add XML doc and regions [Marc C. Brooks] 47 /// * proper implementations of Equals [Marc C. Brooks, Jeffery Sax] 48 /// * uses Math.Log(xx,2) and Math.Pow(xx,2) to get the best accuracy possible when converting doubles [Marc C. Brooks, Jeffery Sax] 49 /// 50 /// What's new in version 2.3 - Marc C. Brooks mailto:IDisposable@gmail.com 01/10/2005 51 /// * fixed double-to-fraction logic to use continued fraction rules to get best possible precistion [bug fix for Syed Mehroz Alam, idea from Jeffery Sax] 52 /// * added static readonly values for NaN, PositiveInfinity, NegativeInfinity [idea from Jeffery Sax] 53 /// * moved comparisons into an implementation of IComparer [idea from Jeffery Sax] 54 /// * no longer throws for NaN(s) involved in Add, Subtract, Multiply, Divide operations [idea from Jeffery Sax] 55 /// * added static readonly values for Zero, MinValue, MaxValue, Epsilon to better mirror double 56 /// * added IsInfinity to better mirror double. 57 /// * added Modulus and % operators 58 /// 59 /// Properties: 60 /// Numerator: Set/Get value for Numerator 61 /// Denominator: Set/Get value for Numerator 62 /// [Note: If you Set either Property, the Fraction should be passed to ReduceFraction at some point.] 63 /// 64 /// Constructors: 65 /// no arguments: initializes fraction as 0/0 = NaN, so don't do that! 66 /// (Numerator, Denominator): initializes fraction with the given numerator and denominator 67 /// values and reduces 68 /// (long): initializes fraction with the given long value 69 /// (double): initializes fraction with the given double value 70 /// (string): initializes fraction with the given string value 71 /// the string can be an in the form of and integer, double or fraction. 72 /// e.g it can be like "123" or "123.321" or "123/456" 73 /// 74 /// Public Methods (Description is given with respective methods' definitions) 75 /// Fraction ToFraction(long) 76 /// Fraction ToFraction(double) 77 /// Fraction ToFraction(string) 78 /// Int32 ToInt32() 79 /// Int64 ToInt64() 80 /// double ToDouble() 81 /// (override) string ToString() 82 /// Fraction Inverse() 83 /// Fraction Inverted(long) 84 /// Fraction Inverted(double) 85 /// ReduceFraction(ref Fraction) 86 /// CrossReducePair(ref Fraction, ref Fraction) 87 /// (override) Equals(object) 88 /// (override) GetHashCode() 89 /// 90 /// Overloaded Operators (overloaded for Fractions, long and double) 91 /// Unary: - 92 /// Binary: +,-,*,/ 93 /// Relational and Logical Operators: ==,!=,<,>,<=,>= (only == and != for long and doubles) 94 /// 95 /// Overloaded user-defined conversions 96 /// Implicit: From long/double/string to Fraction 97 /// Explicit: From Fraction to long/double/string 98 /// </summary> 99 [Serializable, StructLayout(LayoutKind.Sequential)] 100 public struct Fraction : IComparable, IFormattable { 101 #region Constructors 102 /// <summary> 103 /// Construct a Fraction from an integral value 104 /// </summary> 105 /// <param name="wholeNumber">The value (eventual numerator)</param> 106 /// <remarks>The denominator will be 1</remarks> 107 public Fraction(long wholeNumber) { 108 if (wholeNumber == long.MinValue) 109 wholeNumber++; // prevent serious issues later.. 110 111 m_Numerator = wholeNumber; 112 m_Denominator = 1; 113 // no reducing required, we're a whole number 114 } 115 116 /// <summary> 117 /// Construct a Fraction from a floating-point value 118 /// </summary> 119 /// <param name="floatingPointNumber">The value</param> 120 public Fraction(double floatingPointNumber) { 121 this = ToFraction(floatingPointNumber); 122 } 123 124 /// <summary> 125 /// Construct a Fraction from a string in any legal format 126 /// </summary> 127 /// <param name="inValue">A string with a legal fraction input format</param> 128 /// <remarks>Will reduce the fraction to smallest possible denominator</remarks> 129 /// <see>ToFraction(string strValue)</see> 130 public Fraction(string inValue) { 131 this = ToFraction(inValue); 132 } 133 134 /// <summary> 135 /// Construct a Fraction from a numerator, denominator pair 136 /// </summary> 137 /// <param name="numerator">The numerator (top number)</param> 138 /// <param name="denominator">The denominator (bottom number)</param> 139 /// <remarks>Will reduce the fraction to smallest possible denominator</remarks> 140 public Fraction(long numerator, long denominator) { 141 if (numerator == long.MinValue) 142 numerator++; // prevent serious issues later.. 143 144 if (denominator == long.MinValue) 145 denominator++; // prevent serious issues later.. 146 147 m_Numerator = numerator; 148 m_Denominator = denominator; 149 ReduceFraction(ref this); 150 } 151 152 /// <summary> 153 /// Private constructor to synthesize a Fraction for indeterminates (NaN and infinites) 154 /// </summary> 155 /// <param name="type">Kind of inderterminate</param> 156 private Fraction(Indeterminates type) { 157 m_Numerator = (long)type; 158 m_Denominator = 0; 159 // do NOT reduce, we're clean as can be! 160 } 161 #endregion 162 163 #region Properties 164 /// <summary> 165 /// The 'top' part of the fraction 166 /// </summary> 167 /// <example>For 3/4ths, this is the 3</example> 168 public long Numerator { 169 get { 170 return m_Numerator; 171 } 172 set { 173 m_Numerator = value; 174 } 175 } 176 177 /// <summary> 178 /// The 'bottom' part of the fraction 179 /// </summary> 180 /// <example>For 3/4ths, this is the 4</example> 181 public long Denominator { 182 get { 183 return m_Denominator; 184 } 185 set { 186 m_Denominator = value; 187 } 188 } 189 #endregion 190 191 #region Expose constants 192 public static readonly Fraction NaN = new Fraction(Indeterminates.NaN); 193 public static readonly Fraction PositiveInfinity = new Fraction(Indeterminates.PositiveInfinity); 194 public static readonly Fraction NegativeInfinity = new Fraction(Indeterminates.NegativeInfinity); 195 public static readonly Fraction Zero = new Fraction(0, 1); 196 public static readonly Fraction Epsilon = new Fraction(1, Int64.MaxValue); 197 private static readonly double EpsilonDouble = 1.0 / Int64.MaxValue; 198 public static readonly Fraction MaxValue = new Fraction(Int64.MaxValue, 1); 199 public static readonly Fraction MinValue = new Fraction(Int64.MinValue, 1); 200 #endregion 201 202 #region Explicit conversions 203 #region To primitives 204 /// <summary> 205 /// Get the integral value of the Fraction object as int/Int32 206 /// </summary> 207 /// <returns>The (approximate) integer value</returns> 208 /// <remarks>If the value is not a true integer, the fractional part is discarded 209 /// (truncated toward zero). If the valid exceeds the range of an Int32 and exception is thrown.</remarks> 210 /// <exception cref="FractionException">Will throw a FractionException for NaN, PositiveInfinity 211 /// or NegativeInfinity with the InnerException set to a System.NotFiniteNumberException.</exception> 212 /// <exception cref="OverflowException" Will throw a System.OverflowException if the value is too 213 /// large or small to be represented as an Int32.</exception> 214 public Int32 ToInt32() { 215 if (this.m_Denominator == 0) { 216 throw new FractionException(string.Format("Cannot convert {0} to Int32", IndeterminateTypeName(this.m_Numerator)), new System.NotFiniteNumberException()); 217 } 218 219 long bestGuess = this.m_Numerator / this.m_Denominator; 220 221 if (bestGuess > Int32.MaxValue || bestGuess < Int32.MinValue) { 222 throw new FractionException("Cannot convert to Int32", new System.OverflowException()); 223 } 224 225 return (Int32)bestGuess; 226 } 227 228 /// <summary> 229 /// Get the integral value of the Fraction object as long/Int64 230 /// </summary> 231 /// <returns>The (approximate) integer value</returns> 232 /// <remarks>If the value is not a true integer, the fractional part is discarded 233 /// (truncated toward zero). If the valid exceeds the range of an Int32, no special 234 /// handling is guaranteed.</remarks> 235 /// <exception cref="FractionException">Will throw a FractionException for NaN, PositiveInfinity 236 /// or NegativeInfinity with the InnerException set to a System.NotFiniteNumberException.</exception> 237 public Int64 ToInt64() { 238 if (this.m_Denominator == 0) { 239 throw new FractionException(string.Format("Cannot convert {0} to Int64", IndeterminateTypeName(this.m_Numerator)), new System.NotFiniteNumberException()); 240 } 241 242 return this.m_Numerator / this.m_Denominator; 243 } 244 245 /// <summary> 246 /// Get the value of the Fraction object as double with full support for NaNs and infinities 247 /// </summary> 248 /// <returns>The decimal representation of the Fraction, or double.NaN, double.NegativeInfinity 249 /// or double.PositiveInfinity</returns> 250 public double ToDouble() { 251 if (this.m_Denominator == 1) 252 return this.m_Numerator; 253 else if (this.m_Denominator == 0) { 254 switch (NormalizeIndeterminate(this.m_Numerator)) { 255 case Indeterminates.NegativeInfinity: 256 return double.NegativeInfinity; 257 258 case Indeterminates.PositiveInfinity: 259 return double.PositiveInfinity; 260 261 case Indeterminates.NaN: 262 default: // this can't happen 263 return double.NaN; 264 } 265 } else { 266 return (double)this.m_Numerator / (double)this.m_Denominator; 267 } 268 } 269 270 /// <summary> 271 /// Get the value of the Fraction as a string, with proper representation for NaNs and infinites 272 /// </summary> 273 /// <returns>The string representation of the Fraction, or the culture-specific representations of 274 /// NaN, PositiveInfinity or NegativeInfinity.</returns> 275 /// <remarks>The current culture determines the textual representation the Indeterminates</remarks> 276 public override string ToString() { 277 if (this.m_Denominator == 1) { 278 return this.m_Numerator.ToString(); 279 } else if (this.m_Denominator == 0) { 280 return IndeterminateTypeName(this.m_Numerator); 281 } else { 282 return this.m_Numerator.ToString() + "/" + this.m_Denominator.ToString(); 283 } 284 } 285 #endregion 286 287 #region From primitives 288 /// <summary> 289 /// Converts a long value to the exact Fraction 290 /// </summary> 291 /// <param name="inValue">The long to convert</param> 292 /// <returns>An exact representation of the value</returns> 293 public static Fraction ToFraction(long inValue) { 294 return new Fraction(inValue); 295 } 296 297 /// <summary> 298 /// Converts a double value to the approximate Fraction 299 /// </summary> 300 /// <param name="inValue">The double to convert</param> 301 /// <returns>A best-fit representation of the value</returns> 302 /// <remarks>Supports double.NaN, double.PositiveInfinity and double.NegativeInfinity</remarks> 303 public static Fraction ToFraction(double inValue) { 304 // it's one of the indeterminates... which? 305 if (double.IsNaN(inValue)) 306 return NaN; 307 else if (double.IsNegativeInfinity(inValue)) 308 return NegativeInfinity; 309 else if (double.IsPositiveInfinity(inValue)) 310 return PositiveInfinity; 311 else if (inValue == 0.0d) 312 return Zero; 313 314 if (inValue > Int64.MaxValue) 315 throw new OverflowException(string.Format("Double {0} too large", inValue)); 316 317 if (inValue < -Int64.MaxValue) 318 throw new OverflowException(string.Format("Double {0} too small", inValue)); 319 320 if (-EpsilonDouble < inValue && inValue < EpsilonDouble) 321 throw new ArithmeticException(string.Format("Double {0} cannot be represented", inValue)); 322 323 int sign = Math.Sign(inValue); 324 inValue = Math.Abs(inValue); 325 326 return ConvertPositiveDouble(sign, inValue); 327 } 328 329 /// <summary> 330 /// Converts a string to the corresponding reduced fraction 331 /// </summary> 332 /// <param name="inValue">The string representation of a fractional value</param> 333 /// <returns>The Fraction that represents the string</returns> 334 /// <remarks>Four forms are supported, as a plain integer, as a double, or as Numerator/Denominator 335 /// and the representations for NaN and the infinites</remarks> 336 /// <example>"123" = 123/1 and "1.25" = 5/4 and "10/36" = 5/13 and NaN = 0/0 and 337 /// PositiveInfinity = 1/0 and NegativeInfinity = -1/0</example> 338 public static Fraction ToFraction(string inValue) { 339 if (inValue == null || inValue == string.Empty) 340 throw new ArgumentNullException("inValue"); 341 342 // could also be NumberFormatInfo.InvariantInfo 343 NumberFormatInfo info = NumberFormatInfo.CurrentInfo; 344 345 // Is it one of the special symbols for NaN and such... 346 string trimmedValue = inValue.Trim(); 347 348 if (trimmedValue == info.NaNSymbol) 349 return NaN; 350 else if (trimmedValue == info.PositiveInfinitySymbol) 351 return PositiveInfinity; 352 else if (trimmedValue == info.NegativeInfinitySymbol) 353 return NegativeInfinity; 354 else { 355 // Not special, is it a Fraction? 356 int slashPos = inValue.IndexOf('/'); 357 358 if (slashPos > -1) { 359 // string is in the form of Numerator/Denominator 360 long numerator = Convert.ToInt64(inValue.Substring(0, slashPos)); 361 long denominator = Convert.ToInt64(inValue.Substring(slashPos + 1)); 362 363 return new Fraction(numerator, denominator); 364 } else { 365 // the string is not in the form of a fraction 366 // hopefully it is double or integer, do we see a decimal point? 367 int decimalPos = inValue.IndexOf(info.CurrencyDecimalSeparator); 368 369 if (decimalPos > -1) 370 return new Fraction(Convert.ToDouble(inValue)); 371 else 372 return new Fraction(Convert.ToInt64(inValue)); 373 } 374 } 375 } 376 #endregion 377 #endregion 378 379 #region Indeterminate classifications 380 /// <summary> 381 /// Determines if a Fraction represents a Not-a-Number 382 /// </summary> 383 /// <returns>True if the Fraction is a NaN</returns> 384 public bool IsNaN() { 385 if (this.m_Denominator == 0 386 && NormalizeIndeterminate(this.m_Numerator) == Indeterminates.NaN) 387 return true; 388 else 389 return false; 390 } 391 392 /// <summary> 393 /// Determines if a Fraction represents Any Infinity 394 /// </summary> 395 /// <returns>True if the Fraction is Positive Infinity or Negative Infinity</returns> 396 public bool IsInfinity() { 397 if (this.m_Denominator == 0 398 && NormalizeIndeterminate(this.m_Numerator) != Indeterminates.NaN) 399 return true; 400 else 401 return false; 402 } 403 404 /// <summary> 405 /// Determines if a Fraction represents Positive Infinity 406 /// </summary> 407 /// <returns>True if the Fraction is Positive Infinity</returns> 408 public bool IsPositiveInfinity() { 409 if (this.m_Denominator == 0 410 && NormalizeIndeterminate(this.m_Numerator) == Indeterminates.PositiveInfinity) 411 return true; 412 else 413 return false; 414 } 415 416 /// <summary> 417 /// Determines if a Fraction represents Negative Infinity 418 /// </summary> 419 /// <returns>True if the Fraction is Negative Infinity</returns> 420 public bool IsNegativeInfinity() { 421 if (this.m_Denominator == 0 422 && NormalizeIndeterminate(this.m_Numerator) == Indeterminates.NegativeInfinity) 423 return true; 424 else 425 return false; 426 } 427 #endregion 428 429 #region Inversion 430 /// <summary> 431 /// Inverts a Fraction 432 /// </summary> 433 /// <returns>The inverted Fraction (with Denominator over Numerator)</returns> 434 /// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks> 435 public Fraction Inverse() { 436 // don't use the obvious constructor because we do not want it normalized at this time 437 Fraction frac = new Fraction(); 438 439 frac.m_Numerator = this.m_Denominator; 440 frac.m_Denominator = this.m_Numerator; 441 return frac; 442 } 443 444 /// <summary> 445 /// Creates an inverted Fraction 446 /// </summary> 447 /// <returns>The inverted Fraction (with Denominator over Numerator)</returns> 448 /// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks> 449 public static Fraction Inverted(long value) { 450 Fraction frac = new Fraction(value); 451 return frac.Inverse(); 452 } 453 454 /// <summary> 455 /// Creates an inverted Fraction 456 /// </summary> 457 /// <returns>The inverted Fraction (with Denominator over Numerator)</returns> 458 /// <remarks>Does NOT throw for zero Numerators as later use of the fraction will catch the error.</remarks> 459 public static Fraction Inverted(double value) { 460 Fraction frac = new Fraction(value); 461 return frac.Inverse(); 462 } 463 #endregion 464 465 #region Operators 466 #region Unary Negation operator 467 /// <summary> 468 /// Negates the Fraction 469 /// </summary> 470 /// <param name="left">The Fraction to negate</param> 471 /// <returns>The negative version of the Fraction</returns> 472 public static Fraction operator -(Fraction left) { 473 return Negate(left); 474 } 475 #endregion 476 477 #region Addition operators 478 public static Fraction operator +(Fraction left, Fraction right) { 479 return Add(left, right); 480 } 481 482 public static Fraction operator +(long left, Fraction right) { 483 return Add(new Fraction(left), right); 484 } 485 486 public static Fraction operator +(Fraction left, long right) { 487 return Add(left, new Fraction(right)); 488 } 489 490 public static Fraction operator +(double left, Fraction right) { 491 return Add(ToFraction(left), right); 492 } 493 494 public static Fraction operator +(Fraction left, double right) { 495 return Add(left, ToFraction(right)); 496 } 497 #endregion 498 499 #region Subtraction operators 500 public static Fraction operator -(Fraction left, Fraction right) { 501 return Add(left, -right); 502 } 503 504 public static Fraction operator -(long left, Fraction right) { 505 return Add(new Fraction(left), -right); 506 } 507 508 public static Fraction operator -(Fraction left, long right) { 509 return Add(left, new Fraction(-right)); 510 } 511 512 public static Fraction operator -(double left, Fraction right) { 513 return Add(ToFraction(left), -right); 514 } 515 516 public static Fraction operator -(Fraction left, double right) { 517 return Add(left, ToFraction(-right)); 518 } 519 #endregion 520 521 #region Multiplication operators 522 public static Fraction operator *(Fraction left, Fraction right) { 523 return Multiply(left, right); 524 } 525 526 public static Fraction operator *(long left, Fraction right) { 527 return Multiply(new Fraction(left), right); 528 } 529 530 public static Fraction operator *(Fraction left, long right) { 531 return Multiply(left, new Fraction(right)); 532 } 533 534 public static Fraction operator *(double left, Fraction right) { 535 return Multiply(ToFraction(left), right); 536 } 537 538 public static Fraction operator *(Fraction left, double right) { 539 return Multiply(left, ToFraction(right)); 540 } 541 #endregion 542 543 #region Division operators 544 public static Fraction operator /(Fraction left, Fraction right) { 545 return Multiply(left, right.Inverse()); 546 } 547 548 public static Fraction operator /(long left, Fraction right) { 549 return Multiply(new Fraction(left), right.Inverse()); 550 } 551 552 public static Fraction operator /(Fraction left, long right) { 553 return Multiply(left, Inverted(right)); 554 } 555 556 public static Fraction operator /(double left, Fraction right) { 557 return Multiply(ToFraction(left), right.Inverse()); 558 } 559 560 public static Fraction operator /(Fraction left, double right) { 561 return Multiply(left, Inverted(right)); 562 } 563 #endregion 564 565 #region Modulus operators 566 public static Fraction operator %(Fraction left, Fraction right) { 567 return Modulus(left, right); 568 } 569 570 public static Fraction operator %(long left, Fraction right) { 571 return Modulus(new Fraction(left), right); 572 } 573 574 public static Fraction operator %(Fraction left, long right) { 575 return Modulus(left, right); 576 } 577 578 public static Fraction operator %(double left, Fraction right) { 579 return Modulus(ToFraction(left), right); 580 } 581 582 public static Fraction operator %(Fraction left, double right) { 583 return Modulus(left, right); 584 } 585 #endregion 586 587 #region Equal operators 588 public static bool operator ==(Fraction left, Fraction right) { 589 return left.CompareEquality(right, false); 590 } 591 592 public static bool operator ==(Fraction left, long right) { 593 return left.CompareEquality(new Fraction(right), false); 594 } 595 596 public static bool operator ==(Fraction left, double right) { 597 return left.CompareEquality(new Fraction(right), false); 598 } 599 #endregion 600 601 #region Not-equal operators 602 public static bool operator !=(Fraction left, Fraction right) { 603 return left.CompareEquality(right, true); 604 } 605 606 public static bool operator !=(Fraction left, long right) { 607 return left.CompareEquality(new Fraction(right), true); 608 } 609 610 public static bool operator !=(Fraction left, double right) { 611 return left.CompareEquality(new Fraction(right), true); 612 } 613 #endregion 614 615 #region Inequality operators 616 /// <summary> 617 /// Compares two Fractions to see if left is less than right 618 /// </summary> 619 /// <param name="left">The first Fraction</param> 620 /// <param name="right">The second Fraction</param> 621 /// <returns>True if <paramref name="left">left</paramref> is less 622 /// than <paramref name="right">right</paramref></returns> 623 /// <remarks>Special handling for indeterminates exists. <see>IndeterminateLess</see></remarks> 624 /// <exception cref="FractionException">Throws an error if overflows occur while computing the 625 /// difference with an InnerException of OverflowException</exception> 626 public static bool operator <(Fraction left, Fraction right) { 627 return left.CompareTo(right) < 0; 628 } 629 630 /// <summary> 631 /// Compares two Fractions to see if left is greater than right 632 /// </summary> 633 /// <param name="left">The first Fraction</param> 634 /// <param name="right">The second Fraction</param> 635 /// <returns>True if <paramref name="left">left</paramref> is greater 636 /// than <paramref name="right">right</paramref></returns> 637 /// <remarks>Special handling for indeterminates exists. <see>IndeterminateLess</see></remarks> 638 /// <exception cref="FractionException">Throws an error if overflows occur while computing the 639 /// difference with an InnerException of OverflowException</exception> 640 public static bool operator >(Fraction left, Fraction right) { 641 return left.CompareTo(right) > 0; 642 } 643 644 /// <summary> 645 /// Compares two Fractions to see if left is less than or equal to right 646 /// </summary> 647 /// <param name="left">The first Fraction</param> 648 /// <param name="right">The second Fraction</param> 649 /// <returns>True if <paramref name="left">left</paramref> is less than or 650 /// equal to <paramref name="right">right</paramref></returns> 651 /// <remarks>Special handling for indeterminates exists. <see>IndeterminateLessEqual</see></remarks> 652 /// <exception cref="FractionException">Throws an error if overflows occur while computing the 653 /// difference with an InnerException of OverflowException</exception> 654 public static bool operator <=(Fraction left, Fraction right) { 655 return left.CompareTo(right) <= 0; 656 } 657 658 /// <summary> 659 /// Compares two Fractions to see if left is greater than or equal to right 660 /// </summary> 661 /// <param name="left">The first Fraction</param> 662 /// <param name="right">The second Fraction</param> 663 /// <returns>True if <paramref name="left">left</paramref> is greater than or 664 /// equal to <paramref name="right">right</paramref></returns> 665 /// <remarks>Special handling for indeterminates exists. <see>IndeterminateLessEqual</see></remarks> 666 /// <exception cref="FractionException">Throws an error if overflows occur while computing the 667 /// difference with an InnerException of OverflowException</exception> 668 public static bool operator >=(Fraction left, Fraction right) { 669 return left.CompareTo(right) >= 0; 670 } 671 #endregion 672 673 #region Implict conversion from primitive operators 674 /// <summary> 675 /// Implicit conversion of a long integral value to a Fraction 676 /// </summary> 677 /// <param name="value">The long integral value to convert</param> 678 /// <returns>A Fraction whose denominator is 1</returns> 679 public static implicit operator Fraction(long value) { 680 return new Fraction(value); 681 } 682 683 /// <summary> 684 /// Implicit conversion of a double floating point value to a Fraction 685 /// </summary> 686 /// <param name="value">The double value to convert</param> 687 /// <returns>A reduced Fraction</returns> 688 public static implicit operator Fraction(double value) { 689 return new Fraction(value); 690 } 691 692 /// <summary> 693 /// Implicit conversion of a string to a Fraction 694 /// </summary> 695 /// <param name="value">The string to convert</param> 696 /// <returns>A reduced Fraction</returns> 697 public static implicit operator Fraction(string value) { 698 return new Fraction(value); 699 } 700 #endregion 701 702 #region Explicit converstion to primitive operators 703 /// <summary> 704 /// Explicit conversion from a Fraction to an integer 705 /// </summary> 706 /// <param name="frac">the Fraction to convert</param> 707 /// <returns>The integral representation of the Fraction</returns> 708 public static explicit operator int(Fraction frac) { 709 return frac.ToInt32(); 710 } 711 712 /// <summary> 713 /// Explicit conversion from a Fraction to an integer 714 /// </summary> 715 /// <param name="frac">The Fraction to convert</param> 716 /// <returns>The integral representation of the Fraction</returns> 717 public static explicit operator long(Fraction frac) { 718 return frac.ToInt64(); 719 } 720 721 /// <summary> 722 /// Explicit conversion from a Fraction to a double floating-point value 723 /// </summary> 724 /// <param name="frac">The Fraction to convert</param> 725 /// <returns>The double representation of the Fraction</returns> 726 public static explicit operator double(Fraction frac) { 727 return frac.ToDouble(); 728 } 729 730 /// <summary> 731 /// Explicit conversion from a Fraction to a string 732 /// </summary> 733 /// <param name="frac">the Fraction to convert</param> 734 /// <returns>The string representation of the Fraction</returns> 735 public static implicit operator string(Fraction frac) { 736 return frac.ToString(); 737 } 738 #endregion 739 #endregion 740 741 #region Equals and GetHashCode overrides 742 /// <summary> 743 /// Compares for equality the current Fraction to the value passed. 744 /// </summary> 745 /// <param name="obj">A Fraction,</param> 746 /// <returns>True if the value equals the current fraction, false otherwise (including for 747 /// non-Fraction types or null object.</returns> 748 public override bool Equals(object obj) { 749 if (obj == null || !(obj is Fraction)) 750 return false; 751 752 try { 753 Fraction right = (Fraction)obj; 754 return this.CompareEquality(right, false); 755 } 756 catch { 757 // can't throw in an Equals! 758 return false; 759 } 760 } 761 762 /// <summary> 763 /// Returns a hash code generated from the current Fraction 764 /// </summary> 765 /// <returns>The hash code</returns> 766 /// <remarks>Reduces (in-place) the Fraction first.</remarks> 767 public override int GetHashCode() { 768 // insure we're as close to normalized as possible first 769 ReduceFraction(ref this); 770 771 int numeratorHash = this.m_Numerator.GetHashCode(); 772 int denominatorHash = this.m_Denominator.GetHashCode(); 773 774 return (numeratorHash ^ denominatorHash); 775 } 776 #endregion 777 778 #region IComparable member and type-specific version 779 /// <summary> 780 /// Compares an object to this Fraction 781 /// </summary> 782 /// <param name="obj">The object to compare against (null is less than everything)</param> 783 /// <returns>-1 if this is less than <paramref name="obj"></paramref>, 784 /// 0 if they are equal, 785 /// 1 if this is greater than <paramref name="obj"></paramref></returns> 786 /// <remarks>Will convert an object from longs, doubles, and strings as this is a value-type.</remarks> 787 public int CompareTo(object obj) { 788 if (obj == null) 789 return 1; // null is less than anything 790 791 Fraction right; 792 793 if (obj is Fraction) 794 right = (Fraction)obj; 795 else if (obj is long) 796 right = (long)obj; 797 else if (obj is double) 798 right = (double)obj; 799 else if (obj is string) 800 right = (string)obj; 801 else 802 throw new ArgumentException("Must be convertible to Fraction", "obj"); 803 804 return this.CompareTo(right); 805 } 806 807 /// <summary> 808 /// Compares this Fraction to another Fraction 809 /// </summary> 810 /// <param name="right">The Fraction to compare against</param> 811 /// <returns>-1 if this is less than <paramref name="right"></paramref>, 812 /// 0 if they are equal, 813 /// 1 if this is greater than <paramref name="right"></paramref></returns> 814 public int CompareTo(Fraction right) { 815 // if left is an indeterminate, punt to the helper... 816 if (this.m_Denominator == 0) { 817 return IndeterminantCompare(NormalizeIndeterminate(this.m_Numerator), right); 818 } 819 820 // if right is an indeterminate, punt to the helper... 821 if (right.m_Denominator == 0) { 822 // note sign-flip... 823 return -IndeterminantCompare(NormalizeIndeterminate(right.m_Numerator), this); 824 } 825 826 // they're both normal Fractions 827 CrossReducePair(ref this, ref right); 828 829 try { 830 checked { 831 long leftScale = this.m_Numerator * right.m_Denominator; 832 long rightScale = this.m_Denominator * right.m_Numerator; 833 834 if (leftScale < rightScale) 835 return -1; 836 else if (leftScale > rightScale) 837 return 1; 838 else 839 return 0; 840 } 841 } 842 catch (Exception e) { 843 throw new FractionException(string.Format("CompareTo({0}, {1}) error", this, right), e); 844 } 845 } 846 #endregion 847 848 #region IFormattable Members 849 string System.IFormattable.ToString(string format, IFormatProvider formatProvider) { 850 return this.m_Numerator.ToString(format, formatProvider) + "/" + this.m_Denominator.ToString(format, formatProvider); 851 } 852 #endregion 853 854 #region Reduction 855 /// <summary> 856 /// Reduces (simplifies) a Fraction by dividing down to lowest possible denominator (via GCD) 857 /// </summary> 858 /// <param name="frac">The Fraction to be reduced [WILL BE MODIFIED IN PLACE]</param> 859 /// <remarks>Modifies the input arguments in-place! Will normalize the NaN and infinites 860 /// representation. Will set Denominator to 1 for any zero numerator. Moves sign to the 861 /// Numerator.</remarks> 862 /// <example>2/4 will be reduced to 1/2</example> 863 public static void ReduceFraction(ref Fraction frac) { 864 // clean up the NaNs and infinites 865 if (frac.m_Denominator == 0) { 866 frac.m_Numerator = (long)NormalizeIndeterminate(frac.m_Numerator); 867 return; 868 } 869 870 // all forms of zero are alike. 871 if (frac.m_Numerator == 0) { 872 frac.m_Denominator = 1; 873 return; 874 } 875 876 long iGCD = GCD(frac.m_Numerator, frac.m_Denominator); 877 frac.m_Numerator /= iGCD; 878 frac.m_Denominator /= iGCD; 879 880 // if negative sign in denominator 881 if (frac.m_Denominator < 0) { 882 //move negative sign to numerator 883 frac.m_Numerator = -frac.m_Numerator; 884 frac.m_Denominator = -frac.m_Denominator; 885 } 886 } 887 888 /// <summary> 889 /// Cross-reduces a pair of Fractions so that we have the best GCD-reduced values for multiplication 890 /// </summary> 891 /// <param name="frac1">The first Fraction [WILL BE MODIFIED IN PLACE]</param> 892 /// <param name="frac2">The second Fraction [WILL BE MODIFIED IN PLACE]</param> 893 /// <remarks>Modifies the input arguments in-place!</remarks> 894 /// <example>(3/4, 5/9) = (1/4, 5/3)</example> 895 public static void CrossReducePair(ref Fraction frac1, ref Fraction frac2) { 896 // leave the indeterminates alone! 897 if (frac1.m_Denominator == 0 || frac2.m_Denominator == 0) 898 return; 899 900 long gcdTop = GCD(frac1.m_Numerator, frac2.m_Denominator); 901 frac1.m_Numerator = frac1.m_Numerator / gcdTop; 902 frac2.m_Denominator = frac2.m_Denominator / gcdTop; 903 904 long gcdBottom = GCD(frac1.m_Denominator, frac2.m_Numerator); 905 frac2.m_Numerator = frac2.m_Numerator / gcdBottom; 906 frac1.m_Denominator = frac1.m_Denominator / gcdBottom; 907 } 908 #endregion 909 910 #region Implementation 911 #region Convert a double to a fraction 912 private static Fraction ConvertPositiveDouble(int sign, double inValue) { 913 // Shamelessly stolen from http://homepage.smc.edu/kennedy_john/CONFRAC.PDF 914 // with AccuracyFactor == double.Episilon 915 long fractionNumerator = (long)inValue; 916 double fractionDenominator = 1; 917 double previousDenominator = 0; 918 double remainingDigits = inValue; 919 int maxIterations = 594; // found at http://www.ozgrid.com/forum/archive/index.php/t-22530.html 920 921 while (remainingDigits != Math.Floor(remainingDigits) 922 && Math.Abs(inValue - (fractionNumerator / fractionDenominator)) > double.Epsilon) { 923 remainingDigits = 1.0 / (remainingDigits - Math.Floor(remainingDigits)); 924 925 double scratch = fractionDenominator; 926 927 fractionDenominator = (Math.Floor(remainingDigits) * fractionDenominator) + previousDenominator; 928 fractionNumerator = (long)(inValue * fractionDenominator + 0.5); 929 930 previousDenominator = scratch; 931 932 if (maxIterations-- < 0) 933 break; 934 } 935 936 return new Fraction(fractionNumerator * sign, (long)fractionDenominator); 937 } 938 #endregion 939 940 #region Equality helper 941 /// <summary> 942 /// Compares for equality the current Fraction to the value passed. 943 /// </summary> 944 /// <param name="right">A Fraction to compare against</param> 945 /// <param name="notEqualCheck">If true, we're looking for not-equal</param> 946 /// <returns>True if the <paramref name="right"></paramref> equals the current 947 /// fraction, false otherwise. If comparing two NaNs, they are always equal AND 948 /// not-equal.</returns> 949 private bool CompareEquality(Fraction right, bool notEqualCheck) { 950 // insure we're normalized first 951 ReduceFraction(ref this); 952 953 // now normalize the comperand 954 ReduceFraction(ref right); 955 956 if (this.m_Numerator == right.m_Numerator && this.m_Denominator == right.m_Denominator) { 957 // special-case rule, two NaNs are always both equal 958 if (notEqualCheck && this.IsNaN()) 959 return true; 960 else 961 return !notEqualCheck; 962 } else { 963 return notEqualCheck; 964 } 965 } 966 #endregion 967 968 #region Comparison helper 969 /// <summary> 970 /// Determines how this Fraction, of an indeterminate type, compares to another Fraction 971 /// </summary> 972 /// <param name="leftType">What kind of indeterminate</param> 973 /// <param name="right">The other Fraction to compare against</param> 974 /// <returns>-1 if this is less than <paramref name="right"></paramref>, 975 /// 0 if they are equal, 976 /// 1 if this is greater than <paramref name="right"></paramref></returns> 977 /// <remarks>NaN is less than anything except NaN and Negative Infinity. Negative Infinity is less 978 /// than anything except Negative Infinity. Positive Infinity is greater than anything except 979 /// Positive Infinity.</remarks> 980 private static int IndeterminantCompare(Indeterminates leftType, Fraction right) { 981 switch (leftType) { 982 case Indeterminates.NaN: 983 // A NaN is... 984 if (right.IsNaN()) 985 return 0; // equal to a NaN 986 else if (right.IsNegativeInfinity()) 987 return 1; // great than Negative Infinity 988 else 989 return -1; // less than anything else 990 991 case Indeterminates.NegativeInfinity: 992 // Negative Infinity is... 993 if (right.IsNegativeInfinity()) 994 return 0; // equal to Negative Infinity 995 else 996 return -1; // less than anything else 997 998 case Indeterminates.PositiveInfinity: 999 if (right.IsPositiveInfinity()) 1000 return 0; // equal to Positive Infinity 1001 else 1002 return 1; // greater than anything else 1003 1004 default: 1005 // this CAN'T happen, something VERY wrong is going on... 1006 return 0; 1007 } 1008 } 1009 #endregion 1010 1011 #region Math helpers 1012 /// <summary> 1013 /// Negates the Fraction 1014 /// </summary> 1015 /// <param name="frac">Value to negate</param> 1016 /// <returns>A new Fraction that is sign-flipped from the input</returns> 1017 private static Fraction Negate(Fraction frac) { 1018 // for a NaN, it's still a NaN 1019 return new Fraction(-frac.m_Numerator, frac.m_Denominator); 1020 } 1021 1022 /// <summary> 1023 /// Adds two Fractions 1024 /// </summary> 1025 /// <param name="left">A Fraction</param> 1026 /// <param name="right">Another Fraction</param> 1027 /// <returns>Sum of the Fractions. Returns NaN if either Fraction is a NaN.</returns> 1028 /// <exception cref="FractionException">Will throw if an overflow occurs when computing the 1029 /// GCD-normalized values.</exception> 1030 private static Fraction Add(Fraction left, Fraction right) { 1031 if (left.IsNaN() || right.IsNaN()) 1032 return NaN; 1033 1034 long gcd = GCD(left.m_Denominator, right.m_Denominator); // cannot return less than 1 1035 long leftDenominator = left.m_Denominator / gcd; 1036 long rightDenominator = right.m_Denominator / gcd; 1037 1038 try { 1039 checked { 1040 long numerator = left.m_Numerator * rightDenominator + right.m_Numerator * leftDenominator; 1041 long denominator = leftDenominator * rightDenominator * gcd; 1042 1043 return new Fraction(numerator, denominator); 1044 } 1045 } 1046 catch (Exception e) { 1047 throw new FractionException("Add error", e); 1048 } 1049 } 1050 1051 /// <summary> 1052 /// Multiplies two Fractions 1053 /// </summary> 1054 /// <param name="left">A Fraction</param> 1055 /// <param name="right">Another Fraction</param> 1056 /// <returns>Product of the Fractions. Returns NaN if either Fraction is a NaN.</returns> 1057 /// <exception cref="FractionException">Will throw if an overflow occurs. Does a cross-reduce to 1058 /// insure only the unavoidable overflows occur.</exception> 1059 private static Fraction Multiply(Fraction left, Fraction right) { 1060 if (left.IsNaN() || right.IsNaN()) 1061 return NaN; 1062 1063 // this would be unsafe if we were not a ValueType, because we would be changing the 1064 // caller's values. If we change back to a class, must use temporaries 1065 CrossReducePair(ref left, ref right); 1066 1067 try { 1068 checked { 1069 long numerator = left.m_Numerator * right.m_Numerator; 1070 long denominator = left.m_Denominator * right.m_Denominator; 1071 1072 return new Fraction(numerator, denominator); 1073 } 1074 } 1075 catch (Exception e) { 1076 throw new FractionException("Multiply error", e); 1077 } 1078 } 1079 1080 /// <summary> 1081 /// Returns the modulus (remainder after dividing) two Fractions 1082 /// </summary> 1083 /// <param name="left">A Fraction</param> 1084 /// <param name="right">Another Fraction</param> 1085 /// <returns>Modulus of the Fractions. Returns NaN if either Fraction is a NaN.</returns> 1086 /// <exception cref="FractionException">Will throw if an overflow occurs. Does a cross-reduce to 1087 /// insure only the unavoidable overflows occur.</exception> 1088 private static Fraction Modulus(Fraction left, Fraction right) { 1089 if (left.IsNaN() || right.IsNaN()) 1090 return NaN; 1091 1092 try { 1093 checked { 1094 // this will discard any fractional places... 1095 Int64 quotient = (Int64)(left / right); 1096 Fraction whole = new Fraction(quotient * right.m_Numerator, right.m_Denominator); 1097 return left - whole; 1098 } 1099 } 1100 catch (Exception e) { 1101 throw new FractionException("Modulus error", e); 1102 } 1103 } 1104 1105 /// <summary> 1106 /// Computes the greatest common divisor for two values 1107 /// </summary> 1108 /// <param name="left">One value</param> 1109 /// <param name="right">Another value</param> 1110 /// <returns>The greatest common divisor of the two values</returns> 1111 /// <example>(6, 9) returns 3 and (11, 4) returns 1</example> 1112 private static long GCD(long left, long right) { 1113 // take absolute values 1114 if (left < 0) 1115 left = -left; 1116 1117 if (right < 0) 1118 right = -right; 1119 1120 // if we're dealing with any zero or one, the GCD is 1 1121 if (left < 2 || right < 2) 1122 return 1; 1123 1124 do { 1125 if (left < right) { 1126 long temp = left; // swap the two operands 1127 left = right; 1128 right = temp; 1129 } 1130 1131 left %= right; 1132 } while (left != 0); 1133 1134 return right; 1135 } 1136 #endregion 1137 1138 #region Indeterminate helpers 1139 /// <summary> 1140 /// Gives the culture-related representation of the indeterminate types NaN, PositiveInfinity 1141 /// and NegativeInfinity 1142 /// </summary> 1143 /// <param name="numerator">The value in the numerator</param> 1144 /// <returns>The culture-specific string representation of the implied value</returns> 1145 /// <remarks>Only the sign and zero/non-zero information is relevant.</remarks> 1146 private static string IndeterminateTypeName(long numerator) { 1147 // could also be NumberFormatInfo.InvariantInfo 1148 System.Globalization.NumberFormatInfo info = NumberFormatInfo.CurrentInfo; 1149 1150 switch (NormalizeIndeterminate(numerator)) { 1151 case Indeterminates.PositiveInfinity: 1152 return info.PositiveInfinitySymbol; 1153 1154 case Indeterminates.NegativeInfinity: 1155 return info.NegativeInfinitySymbol; 1156 1157 default: // if this happens, something VERY wrong is going on... 1158 case Indeterminates.NaN: 1159 return info.NaNSymbol; 1160 } 1161 } 1162 1163 /// <summary> 1164 /// Gives the normalize representation of the indeterminate types NaN, PositiveInfinity 1165 /// and NegativeInfinity 1166 /// </summary> 1167 /// <param name="numerator">The value in the numerator</param> 1168 /// <returns>The normalized version of the indeterminate type</returns> 1169 /// <remarks>Only the sign and zero/non-zero information is relevant.</remarks> 1170 private static Indeterminates NormalizeIndeterminate(long numerator) { 1171 switch (Math.Sign(numerator)) { 1172 case 1: 1173 return Indeterminates.PositiveInfinity; 1174 1175 case -1: 1176 return Indeterminates.NegativeInfinity; 1177 1178 default: // if this happens, your Math.Sign function is BROKEN! 1179 case 0: 1180 return Indeterminates.NaN; 1181 } 1182 } 1183 1184 // These are used to represent the indeterminate with a Denominator of zero 1185 private enum Indeterminates { 1186 NaN = 0 1187 , 1188 PositiveInfinity = 1 1189 , NegativeInfinity = -1 1190 } 1191 #endregion 1192 1193 #region Member variables 1194 private long m_Numerator; 1195 private long m_Denominator; 1196 #endregion 1197 #endregion 1198 } //end class Fraction 1199 1200 /// <summary> 1201 /// Exception class for Fraction, derived from System.Exception 1202 /// </summary> 1203 public class FractionException : Exception { 1204 /// <summary> 1205 /// Constructs a FractionException 1206 /// </summary> 1207 /// <param name="Message">String associated with the error message</param> 1208 /// <param name="InnerException">Actual inner exception caught</param> 1209 public FractionException(string Message, Exception InnerException) 1210 : base(Message, InnerException) { 1211 } 1212 } //end class FractionException 1213 } //end namespace Mehroz -
branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers-3.3.csproj
r10198 r10200 107 107 <ItemGroup> 108 108 <Compile Include="DoubleArrayExtensions.cs" /> 109 <Compile Include="FractionClass.cs" /> 110 <Compile Include="LiblrsWrapper.cs" /> 109 111 <Compile Include="RealVectorConvexHullSolutionCacheAnalyzer.cs" /> 110 112 <Compile Include="DistanceMatrixToPoints.cs" /> … … 164 166 </ProjectReference> 165 167 </ItemGroup> 168 <ItemGroup> 169 <Content Include="liblrs.dll"> 170 <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> 171 </Content> 172 </ItemGroup> 166 173 <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 167 174 <PropertyGroup> -
branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.Analyzers/3.3/LiblrsWrapper.cs
r10198 r10200 21 21 22 22 using System; 23 using System.Collections.Generic; 24 using System.Linq; 23 25 using System.Runtime.InteropServices; 24 26 25 namespace Testliblrs {27 namespace HeuristicLab.Analysis.AlgorithmBehavior.Analyzers { 26 28 public static class LiblrsWrapper { 29 public static double CalculateVolume(List<double[]> points) { 30 double result = 0.0; 31 int dimension = points.First().Length; 32 int numPoints = points.Count(); 33 34 Int32[] num = new Int32[dimension * numPoints]; 35 Int32[] den = new Int32[dimension * numPoints]; 36 37 for (int i = 0; i < numPoints; i++) { 38 for (int j = 0; j < dimension; j++) { 39 var fraction = new Fraction(points[i][j]); 40 //TODO: fix possible overflow 41 num[i * dimension + j] = (int)fraction.Numerator; 42 den[i * dimension + j] = (int)fraction.Denominator; 43 } 44 } 45 result = calculate_volume(numPoints, dimension, num, den); 46 return result; 47 } 48 27 49 [System.Runtime.InteropServices.DllImportAttribute("liblrs.dll", EntryPoint = "calculate_volume")] 28 50 public static extern double calculate_volume(int numPoints, int dimension, [In] Int32[] num, [In] Int32[] den); -
branches/HeuristicLab.Analysis.AlgorithmBehavior/HeuristicLab.Analysis.AlgorithmBehavior.sln
r10024 r10200 5 5 ProjectSection(SolutionItems) = preProject 6 6 Build.cmd = Build.cmd 7 Performance1.psess = Performance1.psess 7 8 PreBuildEvent.cmd = PreBuildEvent.cmd 8 9 EndProjectSection … … 23 24 EndProject 24 25 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Analysis.SolutionCaching.Views-3.3", "HeuristicLab.Analysis.SolutionCaching.Views\3.3\HeuristicLab.Analysis.SolutionCaching.Views-3.3.csproj", "{3977F98A-3D59-4D02-A6D3-51021BCEB488}" 26 EndProject 27 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PerformanceTests", "PerformanceTests\PerformanceTests.csproj", "{8044B249-01E1-4C7E-8A21-E3C5C1DE0714}" 25 28 EndProject 26 29 Global … … 102 105 {3977F98A-3D59-4D02-A6D3-51021BCEB488}.Release|x64.ActiveCfg = Release|Any CPU 103 106 {3977F98A-3D59-4D02-A6D3-51021BCEB488}.Release|x86.ActiveCfg = Release|Any CPU 107 {8044B249-01E1-4C7E-8A21-E3C5C1DE0714}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 108 {8044B249-01E1-4C7E-8A21-E3C5C1DE0714}.Debug|Any CPU.Build.0 = Debug|Any CPU 109 {8044B249-01E1-4C7E-8A21-E3C5C1DE0714}.Debug|x64.ActiveCfg = Debug|Any CPU 110 {8044B249-01E1-4C7E-8A21-E3C5C1DE0714}.Debug|x86.ActiveCfg = Debug|Any CPU 111 {8044B249-01E1-4C7E-8A21-E3C5C1DE0714}.Release|Any CPU.ActiveCfg = Release|Any CPU 112 {8044B249-01E1-4C7E-8A21-E3C5C1DE0714}.Release|Any CPU.Build.0 = Release|Any CPU 113 {8044B249-01E1-4C7E-8A21-E3C5C1DE0714}.Release|x64.ActiveCfg = Release|Any CPU 114 {8044B249-01E1-4C7E-8A21-E3C5C1DE0714}.Release|x86.ActiveCfg = Release|Any CPU 104 115 EndGlobalSection 105 116 GlobalSection(SolutionProperties) = preSolution 106 117 HideSolutionNode = FALSE 107 118 EndGlobalSection 119 GlobalSection(Performance) = preSolution 120 HasPerformanceSessions = true 121 EndGlobalSection 108 122 EndGlobal -
branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/ctest_liblrs/ctest_liblrs.vcxproj
r10198 r10200 6 6 <Platform>Win32</Platform> 7 7 </ProjectConfiguration> 8 <ProjectConfiguration Include="Debug|x64"> 9 <Configuration>Debug</Configuration> 10 <Platform>x64</Platform> 11 </ProjectConfiguration> 8 12 <ProjectConfiguration Include="Release|Win32"> 9 13 <Configuration>Release</Configuration> 10 14 <Platform>Win32</Platform> 15 </ProjectConfiguration> 16 <ProjectConfiguration Include="Release|x64"> 17 <Configuration>Release</Configuration> 18 <Platform>x64</Platform> 11 19 </ProjectConfiguration> 12 20 </ItemGroup> … … 22 30 <CharacterSet>MultiByte</CharacterSet> 23 31 </PropertyGroup> 32 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> 33 <ConfigurationType>Application</ConfigurationType> 34 <UseDebugLibraries>true</UseDebugLibraries> 35 <PlatformToolset>v110</PlatformToolset> 36 <CharacterSet>MultiByte</CharacterSet> 37 </PropertyGroup> 24 38 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> 39 <ConfigurationType>Application</ConfigurationType> 40 <UseDebugLibraries>false</UseDebugLibraries> 41 <PlatformToolset>v110</PlatformToolset> 42 <WholeProgramOptimization>true</WholeProgramOptimization> 43 <CharacterSet>MultiByte</CharacterSet> 44 </PropertyGroup> 45 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> 25 46 <ConfigurationType>Application</ConfigurationType> 26 47 <UseDebugLibraries>false</UseDebugLibraries> … … 35 56 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 36 57 </ImportGroup> 58 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> 59 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 60 </ImportGroup> 37 61 <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 62 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 63 </ImportGroup> 64 <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> 38 65 <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> 39 66 </ImportGroup> … … 44 71 <ReferencePath>$(SolutionDir)Debug;$(ReferencePath)</ReferencePath> 45 72 </PropertyGroup> 73 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> 74 <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath> 75 <LibraryPath>$(SolutionDir)x64\Debug;$(LibraryPath)</LibraryPath> 76 <ReferencePath>$(SolutionDir)Debug;$(ReferencePath)</ReferencePath> 77 </PropertyGroup> 46 78 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> 47 79 <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath> 48 80 <LibraryPath>$(SolutionDir)\Release;$(LibraryPath)</LibraryPath> 49 81 </PropertyGroup> 82 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> 83 <IncludePath>$(SolutionDir);$(IncludePath)</IncludePath> 84 <LibraryPath>$(SolutionDir)\Release;$(LibraryPath)</LibraryPath> 85 </PropertyGroup> 50 86 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> 87 <ClCompile> 88 <WarningLevel>Level3</WarningLevel> 89 <Optimization>Disabled</Optimization> 90 <SDLCheck>true</SDLCheck> 91 </ClCompile> 92 <Link> 93 <GenerateDebugInformation>true</GenerateDebugInformation> 94 <AdditionalDependencies>liblrs.lib;%(AdditionalDependencies)</AdditionalDependencies> 95 </Link> 96 </ItemDefinitionGroup> 97 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> 51 98 <ClCompile> 52 99 <WarningLevel>Level3</WarningLevel> … … 74 121 </Link> 75 122 </ItemDefinitionGroup> 123 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> 124 <ClCompile> 125 <WarningLevel>Level3</WarningLevel> 126 <Optimization>MaxSpeed</Optimization> 127 <FunctionLevelLinking>true</FunctionLevelLinking> 128 <IntrinsicFunctions>true</IntrinsicFunctions> 129 <SDLCheck>true</SDLCheck> 130 </ClCompile> 131 <Link> 132 <GenerateDebugInformation>true</GenerateDebugInformation> 133 <EnableCOMDATFolding>true</EnableCOMDATFolding> 134 <OptimizeReferences>true</OptimizeReferences> 135 <AdditionalDependencies>$(SolutionDir)Release\liblrs.lib;%(AdditionalDependencies)</AdditionalDependencies> 136 </Link> 137 </ItemDefinitionGroup> 76 138 <ItemGroup> 77 139 <ClCompile Include="main.cpp" /> -
branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/extfunc.c
r10198 r10200 56 56 /* now flags in lrs_dat can be set */ 57 57 Q->m=numPoints; /* number of input rows = number of vertices */ 58 Q->n=dimension; /*TODO: +1?*/ /* number of input columns (dimension + 1 )*/58 Q->n=dimension; /* number of input columns */ 59 59 Q->hull = TRUE; /* convex hull problem: facet enumeration */ 60 60 Q->polytope= TRUE; /* input is a polytope */ -
branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs.sln
r10198 r10200 52 52 {B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|Win32.ActiveCfg = Debug|Win32 53 53 {B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|Win32.Build.0 = Debug|Win32 54 {B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|x64.ActiveCfg = Debug| Win3255 {B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|x64.Build.0 = Debug| Win3254 {B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|x64.ActiveCfg = Debug|x64 55 {B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Debug|x64.Build.0 = Debug|x64 56 56 {B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Release|Any CPU.ActiveCfg = Release|Win32 57 57 {B6D2A50A-D977-4F8F-8BCA-08591D6BB52D}.Release|Mixed Platforms.ActiveCfg = Release|Win32 -
branches/HeuristicLab.Analysis.AlgorithmBehavior/liblrs/liblrs/liblrs.vcxproj
r10198 r10200 35 35 <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> 36 36 <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> 37 <ConfigurationType> StaticLibrary</ConfigurationType>37 <ConfigurationType>DynamicLibrary</ConfigurationType> 38 38 <UseDebugLibraries>true</UseDebugLibraries> 39 39 <PlatformToolset>v110</PlatformToolset> … … 93 93 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> 94 94 <ClCompile> 95 <PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions) ;B64</PreprocessorDefinitions>95 <PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> 96 96 </ClCompile> 97 97 </ItemDefinitionGroup> 98 98 <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> 99 99 <ClCompile> 100 <PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions) ;B64</PreprocessorDefinitions>100 <PreprocessorDefinitions>_WINDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions> 101 101 </ClCompile> 102 102 </ItemDefinitionGroup>
Note: See TracChangeset
for help on using the changeset viewer.