Advertisement
Guest User

Untitled

a guest
Aug 28th, 2015
64
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 17.01 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3.  
  4. public class Polynomial
  5. {
  6. #region Fields
  7. /// <summary>
  8. /// The Internal Array that Stores the Coefficients as they are Input.
  9. /// To Access Coefficients use Indexer.
  10. /// </summary>
  11. Complex[] Coefficients { get; set; }
  12. #endregion
  13.  
  14. #region Constructors
  15. /// <summary>
  16. /// Creates a Polynomial from an Array of Coefficients.
  17. /// </summary>
  18. /// <param name="coefficients">The Coefficients in Decreasing Order of Degrees.</param>
  19. public Polynomial(params Complex[] coefficients)
  20. {
  21. if (coefficients == null || coefficients.Length < 1) throw new IndexOutOfRangeException();
  22. else Coefficients = coefficients;
  23. Clean();
  24. if (Degree < 0) throw new Exception("Degree must be atleast one.");
  25. }
  26.  
  27. /// <summary>
  28. /// Computes the monomial x^degree.
  29. /// </summary>
  30. public static Polynomial Monomial(int degree)
  31. {
  32. if (degree < 0) throw new Exception("Degree must be atleast one.");
  33.  
  34. List<Complex> coeffs = new List<Complex>(degree + 1);
  35.  
  36. for (int i = 0; i < degree; i++) coeffs.Add(0);
  37. coeffs.Add(1);
  38. coeffs.Reverse();
  39.  
  40. return new Polynomial(coeffs.ToArray());
  41. }
  42. #endregion
  43.  
  44. #region Indexer
  45. /// <summary>
  46. /// Gets or Sets the Coefficient of a Term.
  47. /// </summary>
  48. /// <param name="index">The Degree of the Required Term.</param>
  49. /// <returns>The Coefficient of the specified Degree Term.</returns>
  50. public Complex this[int index]
  51. {
  52. get
  53. {
  54. if (index > Degree | index < 0) return 0;
  55. return Coefficients[Degree - index];
  56. }
  57. set
  58. {
  59. if (index > Degree | index < 0) throw new IndexOutOfRangeException();
  60. Complex[] temp = (Complex[])Coefficients.Clone();
  61. Coefficients[Degree - index] = value;
  62. Clean();
  63. if (Degree < 1)
  64. {
  65. Coefficients = temp;
  66. throw new ArgumentException("Degree cannot be less than 1.");
  67. }
  68. }
  69. }
  70. #endregion
  71.  
  72. #region Properties
  73. /// <summary>
  74. /// Gets the Degree of the Polynomial.
  75. /// </summary>
  76. public int Degree { get { return Coefficients.Length - 1; } }
  77. #endregion
  78.  
  79. #region Methods
  80. /// <summary>
  81. /// Removes leading Zero terms.
  82. /// </summary>
  83. void Clean()
  84. {
  85. int i;
  86.  
  87. for (i = Degree; i >= 0 && this[i] == 0; --i) ;
  88.  
  89. List<Complex> coeffs = new List<Complex>(i + 1);
  90.  
  91. for (int k = 0; k <= i; ++k) coeffs.Add(this[k]);
  92. coeffs.Reverse();
  93.  
  94. Coefficients = coeffs.ToArray();
  95. }
  96.  
  97. /// <summary>
  98. /// Evaluates the value of the Polynomial at a Value.
  99. /// </summary>
  100. /// <param name="Z">The Complex Number to Evaluate the Polynomial at.</param>
  101. /// <returns>The Value of the Polynomial at the input Value.</returns>
  102. public Complex Evaluate(Complex Z)
  103. {
  104. Complex Result = this[Degree];
  105.  
  106. for (int i = Degree - 1; i >= 0; --i) Result = this[i] + Z * Result;
  107.  
  108. return Result;
  109. }
  110. #endregion
  111.  
  112. /// <summary>
  113. /// Divides Dividend Polynomial by Divisor Polynomial
  114. /// </summary>
  115. /// <returns>Quotient Polynomial</returns>
  116. public static Polynomial Divide(Polynomial Dividend, Polynomial Divisor, out Polynomial Remainder)
  117. {
  118. if (Dividend.Degree < Divisor.Degree) throw new InvalidOperationException();
  119.  
  120. List<Complex> Result = new List<Complex>();
  121.  
  122. Remainder = (Polynomial)Dividend.MemberwiseClone();
  123.  
  124. int Offset = Dividend.Degree - Divisor.Degree;
  125.  
  126. for (int i = 0; i <= Offset; ++i)
  127. {
  128. Result.Add(Remainder.Coefficients[0] / Divisor.Coefficients[0]);
  129.  
  130. Remainder -= Result[i] * (Divisor * Monomial(Offset - i));
  131. }
  132.  
  133. return new Polynomial(Result.ToArray());
  134. }
  135.  
  136. /// <summary>
  137. /// Normalizes the polynomial, i.e. divides each coefficient by the
  138. /// coefficient of the greatest term if it is != 1.
  139. /// </summary>
  140. public void Normalize()
  141. {
  142. this.Clean();
  143. if (this[Degree] != 1) for (int k = 0; k <= Degree; k++) this[k] /= this[Degree];
  144. }
  145.  
  146. #region Parsing
  147. /// <summary>
  148. /// Parses a Real Polynomial from a String.
  149. /// </summary>
  150. /// <param name="s">The String representation of the Real Polynomial to Parse. Eg: 4x^3 + 3x^2 - 23x + 20</param>
  151. public static Polynomial Parse(string s)
  152. {
  153. Dictionary<int, double> Work = new Dictionary<int, double>();
  154. string temp = string.Empty;
  155. s = s.Trim();
  156. int degree = 0;
  157.  
  158. try
  159. {
  160. foreach (char c in s)
  161. {
  162. if (c == '+' || c == '-')
  163. {
  164. KeyValuePair<int, double> Pair = ParseTerm(temp);
  165. Work.Add(Pair.Key, Pair.Value);
  166. if (Pair.Key > degree) degree = Pair.Key;
  167. temp = c.ToString();
  168. }
  169. else if (c == '=') break;
  170. else temp += c;
  171. }
  172.  
  173. KeyValuePair<int, double> PairX = ParseTerm(temp);
  174. Work.Add(PairX.Key, PairX.Value);
  175. }
  176. catch { throw new FormatException("Input string was not of the correct format."); }
  177. return new Polynomial(Work, degree);
  178. }
  179.  
  180. Polynomial(Dictionary<int, double> a, int degree)
  181. {
  182. List<Complex> list = new List<Complex>(degree);
  183. for (int i = 0; i <= degree; ++i) list.Add(a.ContainsKey(i) ? a[i] : 0);
  184. list.Reverse();
  185. Coefficients = list.ToArray();
  186. Clean();
  187. }
  188.  
  189. static KeyValuePair<int, double> ParseTerm(string s)
  190. {
  191. int Power;
  192. double Coefficient;
  193.  
  194. if (s.Length > 0)
  195. {
  196. if (s.IndexOf("x^") > -1)
  197. {
  198. string coeff = s.Substring(0, s.IndexOf("x^")).Replace("+", "").Replace(" ", "");
  199. int IndexOfX = s.IndexOf("x^");
  200. string pow = s.Substring(IndexOfX + 2, (s.Length - 1) - (IndexOfX + 1));
  201. if (coeff == "-") Coefficient = -1;
  202. else if (coeff == "+" | coeff == "") Coefficient = 1;
  203. else Coefficient = Double.Parse(coeff);
  204. Power = int.Parse(pow);
  205. }
  206. else if (s.IndexOf("x") > -1)
  207. {
  208. string coeff = s.Substring(0, s.IndexOf("x")).Replace("+", "").Replace(" ", "");
  209. if (coeff == "-") Coefficient = -1;
  210. else if (coeff == "+" | coeff == "") Coefficient = 1;
  211. else Coefficient = Double.Parse(coeff);
  212. Power = 1;
  213. }
  214. else
  215. {
  216. Power = 0;
  217. Coefficient = Double.Parse(s.Replace("+", "").Replace(" ", ""));
  218. }
  219. }
  220. else Coefficient = Power = 0;
  221.  
  222. return new KeyValuePair<int, double>(Power, Coefficient);
  223. }
  224.  
  225. #endregion
  226.  
  227. #region Calculus
  228. /// <summary>
  229. /// Differentiates given polynomial p.
  230. /// </summary>
  231. /// <param name="p"></param>
  232. /// <returns></returns>
  233. public Polynomial Derivative
  234. {
  235. get
  236. {
  237. List<Complex> buf = new List<Complex>(Degree);
  238.  
  239. for (int i = 0; i < Degree; i++) buf.Add((i + 1) * this[i + 1]);
  240.  
  241. buf.Reverse();
  242.  
  243. return new Polynomial(buf.ToArray());
  244. }
  245. }
  246.  
  247. /// <summary>
  248. /// Integrates given polynomial p.
  249. /// </summary>
  250. /// <param name="p"></param>
  251. /// <returns></returns>
  252. public Polynomial Integral
  253. {
  254. get
  255. {
  256. List<Complex> buf = new List<Complex>(Degree + 2);
  257.  
  258. for (int i = 1; i < Degree + 2; i++) buf.Add(this[i - 1] / i);
  259.  
  260. buf.Reverse();
  261.  
  262. buf.Add(0);
  263.  
  264. return new Polynomial(buf.ToArray());
  265. }
  266. }
  267.  
  268. public Complex Differentiate(Complex Z) { return Derivative.Evaluate(Z); }
  269.  
  270. public Complex Intergrate(Complex LowerLimit, Complex UpperLimit)
  271. {
  272. Polynomial Px = Integral;
  273. return Integral.Evaluate(UpperLimit) - Integral.Evaluate(LowerLimit);
  274. }
  275. #endregion
  276.  
  277. #region Override
  278. public override bool Equals(object obj)
  279. {
  280. return (obj is Polynomial) ? this == (Polynomial)obj : false;
  281. }
  282.  
  283. public static new bool Equals(object o1, object o2)
  284. {
  285. return (o1 is Polynomial && o2 is Polynomial) ? (Polynomial)o1 == (Polynomial)o2 : false;
  286. }
  287. #endregion
  288.  
  289. #region Operator Overloading
  290. public static bool operator ==(Polynomial P1, Polynomial P2)
  291. {
  292. if (P1.Degree != P2.Degree) return false;
  293.  
  294. for (int i = 0; i <= P1.Degree; ++i) if (P1[i] != P2[i]) return false;
  295.  
  296. return true;
  297. }
  298.  
  299. public static bool operator !=(Polynomial P1, Polynomial P2) { return !(P1 == P2); }
  300.  
  301. /// <summary>
  302. /// Adds two Polynomial.
  303. /// </summary>
  304. /// <param name="P1">First Polynomial</param>
  305. /// <param name="P2">Second Polynomial</param>
  306. /// <returns>Resultant Polynomial</returns>
  307. public static Polynomial operator +(Polynomial P1, Polynomial P2)
  308. {
  309. int MaxDegree = Math.Max(P1.Degree, P2.Degree);
  310. List<Complex> Coeffs = new List<Complex>();
  311.  
  312. for (int i = 0; i <= MaxDegree; ++i) Coeffs.Add(P1[i] + P2[i]);
  313.  
  314. Coeffs.Reverse();
  315.  
  316. return new Polynomial(Coeffs.ToArray());
  317. }
  318.  
  319. public static Polynomial operator -(Polynomial P1, Polynomial P2)
  320. {
  321. return P1 + (-P2);
  322. }
  323.  
  324. public static Polynomial operator -(Polynomial P)
  325. {
  326. List<Complex> Coeffs = new List<Complex>();
  327.  
  328. for (int i = 0; i <= P.Degree; ++i) Coeffs.Add(-P[i]);
  329.  
  330. Coeffs.Reverse();
  331.  
  332. return new Polynomial(Coeffs.ToArray());
  333. }
  334.  
  335. public static Polynomial operator *(Polynomial P, Complex Z)
  336. {
  337. List<Complex> Coeffs = new List<Complex>();
  338.  
  339. for (int i = 0; i <= P.Degree; ++i) Coeffs.Add(Z * P[i]);
  340.  
  341. Coeffs.Reverse();
  342.  
  343. return new Polynomial(Coeffs.ToArray());
  344. }
  345.  
  346. public static Polynomial operator *(Complex Z, Polynomial P) { return P * Z; }
  347.  
  348. public static Polynomial operator *(Polynomial P1, Polynomial P2)
  349. {
  350. int MaxDegree = P1.Degree + P2.Degree;
  351. List<Complex> Coeffs = new List<Complex>(MaxDegree);
  352.  
  353. for (int i = 0; i <= MaxDegree; ++i) Coeffs.Add(0);
  354.  
  355. for (int i = 0; i <= P1.Degree; ++i) for (int j = 0; j <= P2.Degree; ++j) Coeffs[i + j] += P1[i] * P2[j];
  356.  
  357. Coeffs.Reverse();
  358.  
  359. return new Polynomial(Coeffs.ToArray());
  360. }
  361.  
  362. public static Polynomial operator /(Polynomial P, Complex Z)
  363. {
  364. List<Complex> Coeffs = new List<Complex>();
  365.  
  366. for (int i = 0; i <= P.Degree; ++i) Coeffs.Add(P[i] / Z);
  367.  
  368. Coeffs.Reverse();
  369.  
  370. return new Polynomial(Coeffs.ToArray());
  371. }
  372.  
  373. public static Polynomial operator ^(Polynomial P, int I)
  374. {
  375. if (I < 1) throw new Exception("Exponent must be greater than Zero.");
  376. Polynomial Result = P;
  377. for (int i = 1; i < I; ++i) Result *= P;
  378. return Result;
  379. }
  380. #endregion
  381.  
  382. #region Roots
  383. /// <summary>
  384. /// Gets the Sum of Roots of the Polynomial.
  385. /// </summary>
  386. public Complex SumOfRoots { get { return -Coefficients[1] / Coefficients[0]; } }
  387.  
  388. /// <summary>
  389. /// Gets the Product of Roots of the Polynomial.
  390. /// </summary>
  391. public Complex ProductOfRoots { get { return Math.Pow(-1, Degree) * Coefficients[Degree] / Coefficients[0]; } }
  392.  
  393. /// <summary>
  394. /// Gets the Roots (or Zeroes or Solutions) of the Polynomial.
  395. /// </summary>
  396. public ComplexPolynomialRootFinder Roots
  397. {
  398. get
  399. {
  400. if (Degree < 1) throw new Exception("A Zero Degree Polynomial cannot be solved.");
  401. return new ComplexPolynomialRootFinder(Coefficients);
  402. }
  403. }
  404. #endregion
  405.  
  406. #region ToString
  407. /// <summary>
  408. /// Gets a String Representing the Polynomial.
  409. /// </summary>
  410. public override string ToString()
  411. {
  412. string Result = "p(x) = ";
  413.  
  414. for (int i = Coefficients.Length; i > 1; --i)
  415. {
  416. Complex Val = Coefficients[Coefficients.Length - i];
  417.  
  418. bool NotPurelyRealImag = !Val.IsReal && !Val.IsPurelyImaginary;
  419. bool IsNegative = Val.Imaginary < 0 && Val.Real < 0;
  420.  
  421. bool ImagPossitive = Val.IsPurelyImaginary && Val.Imaginary > 0;
  422. bool ImagNegative = Val.IsPurelyImaginary && Val.Imaginary < 0;
  423.  
  424. bool RealPossitive = Val.IsReal && Val.Real > 0;
  425. bool RealNegative = Val.IsReal && Val.Real < 0;
  426.  
  427. if (Val == 0) continue;
  428. else
  429. {
  430. if (i != Coefficients.Length && ((NotPurelyRealImag && !IsNegative) || ImagPossitive || RealPossitive)) Result += " + ";
  431. else if (RealNegative || ImagNegative || IsNegative) Result += " - ";
  432. if (NotPurelyRealImag) Result += "(";
  433. if (Val != 1 && Val != -1 && Val != Complex.Iota && Val != -Complex.Iota)
  434. {
  435. if (IsNegative) Result += (-Val).ToString();
  436. else if (Val.Imaginary == 0) Result += Math.Abs(Val.Real).ToString();
  437. else if (Val.Real == 0) Result += Math.Abs(Val.Imaginary).ToString() + "i";
  438. else Result += Val.ToString();
  439. }
  440. else if (Val == Complex.Iota || Val == -Complex.Iota) Result += "i";
  441. if (NotPurelyRealImag) Result += ")";
  442. Result += i - 1 == 1 ? "x" : "x" + Superscript(i - 1);
  443. }
  444. }
  445. Complex C = Coefficients[Coefficients.Length - 1];
  446.  
  447. if (C != 0)
  448. {
  449. if ((C.IsReal && C.Real > 0) || ((!C.IsReal && !C.IsPurelyImaginary) && !(C.Imaginary < 0 && C.Real < 0)) || (C.IsPurelyImaginary && C.Imaginary > 0))
  450. Result += " + ";
  451. else if ((C.IsReal && C.Real < 0) || (C.IsPurelyImaginary && C.Imaginary < 0) || (C.Imaginary < 0 && C.Real < 0)) Result += " - ";
  452. if (!C.IsReal && !C.IsPurelyImaginary) Result += "(";
  453. if (C != 1 && C != -1 && C != Complex.Iota && C != -Complex.Iota)
  454. {
  455. if (C.Imaginary < 0 && C.Real < 0) Result += (-C).ToString();
  456. else if (C.IsReal) Result += Math.Abs(C.Real).ToString();
  457. else if (C.IsPurelyImaginary) Result += Math.Abs(C.Imaginary).ToString() + "i";
  458. else Result += C.ToString();
  459. }
  460. else if (C == Complex.Iota || C == -Complex.Iota) Result += "i";
  461. else Result += 1;
  462. if (!C.IsReal && !C.IsPurelyImaginary) Result += ")";
  463. }
  464.  
  465. return Result;
  466. }
  467.  
  468. /// <summary>
  469. /// Returns the provided number in Superscript form.
  470. /// </summary>
  471. /// <param name="n">The number to transform into Superscript.</param>
  472. /// <returns>The Superscript form of the provided number.</returns>
  473. static string Superscript(int n)
  474. {
  475. string Result = string.Empty;
  476.  
  477. foreach (char i in n.ToString())
  478. {
  479. switch (i)
  480. {
  481. case '0': Result += '⁰'; break;
  482. case '1': Result += '¹'; break;
  483. case '2': Result += '²'; break;
  484. case '3': Result += '³'; break;
  485. case '4': Result += '⁴'; break;
  486. case '5': Result += '⁵'; break;
  487. case '6': Result += '⁶'; break;
  488. case '7': Result += '⁷'; break;
  489. case '8': Result += '⁸'; break;
  490. case '9': Result += '⁹'; break;
  491. }
  492. }
  493.  
  494. return Result;
  495. }
  496. #endregion
  497. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement