public int CompareTo(Radical other) { var result = (Sign * Rational.Abs(RaisedToIndexPower)) .CompareTo(other.Sign * Rational.Abs(other.RaisedToIndexPower)); return(result); }
public void RationalAbsTest() { Rational.Abs(new Rational(1, 2)).ShouldBe(new Rational(1, 2)); Rational.Abs(new Rational(-1, 2)).ShouldBe(new Rational(1, 2)); Rational.Abs(Rational.NegativeInfinity).ShouldBe(Rational.PositiveInfinity); Rational.Abs(Rational.PositiveInfinity).ShouldBe(Rational.PositiveInfinity); Rational.Abs(Rational.NaN).ShouldBe(Rational.NaN); }
public void AbsoluteNaN() { // arrange var input = Rational.NaN; // action var result = Rational.Abs(input); // assert Assert.Equal(Rational.NaN, result); }
public void Absolute5() { // arrange var p = new Rational(0, 10); // action var q = -p; // assert Assert.Equal(p, Rational.Abs(q)); }
public void Absolute4() { // arrange var p = new Rational(-1, -2); // action var q = -p; // assert Assert.Equal((Rational)1 / 2, Rational.Abs(q)); }
private Rational StarDiscrepency(List <Rational> s) { s.Sort(); Rational d = 0; for (int i = 1; i < s.Count; i++) { d = Rational.Max(d, Rational.Abs(i / (Rational)s.Count - s[i])); } return(d); }
public bool IsXeqYRow(int rowIndex) { var row = matrix[rowIndex]; if (row.NonDefaultElementsCount != 2) { return(false); } var k1 = default(Rational); var k2 = default(Rational); var k1Set = false; var k2Set = false; foreach (var pair in row.GetElements()) { if (pair.Key == row.Length - 1) { // To make the code more robust if (pair.Value != 0) { return(false); } } if (pair.Value.IsMinValue || Rational.Abs(pair.Value) != 1) { return(false); } if (!k1Set) { k1 = pair.Value; k1Set = true; continue; } if (!k2Set) { k2 = pair.Value; k2Set = true; break; } } return((k1 * k2) == -1); }
public ComplexPart Abs() { return(ComplexPart.Create(_value.Abs())); }
public static BigDecimal PowRound(BigDecimal x, Rational q) { /** Special cases: x^1=x and x^0 = 1 */ if (q.CompareTo(BigInteger.One) == 0) return x; if (q.Sign == 0) return BigDecimal.One; if (q.IsInteger) { /* We are sure that the denominator is positive here, because normalize() has been * called during constrution etc. */ return PowRound(x, q.Numerator); } /* Refuse to operate on the general negative basis. The integer q have already been handled above. */ if (x.CompareTo(BigDecimal.Zero) < 0) throw new ArithmeticException("Cannot power negative " + x); if (q.IsIntegerFraction) { /* Newton method with first estimate in double precision. * The disadvantage of this first line here is that the result must fit in the * standard range of double precision numbers exponents. */ double estim = System.Math.Pow(x.ToDouble(), q.ToDouble()); var res = new BigDecimal(estim); /* The error in x^q is q*x^(q-1)*Delta(x). * The relative error is q*Delta(x)/x, q times the relative error of x. */ var reserr = new BigDecimal(0.5*q.Abs().ToDouble() *x.Ulp().Divide(x.Abs(), MathContext.Decimal64).ToDouble()); /* The main point in branching the cases above is that this conversion * will succeed for numerator and denominator of q. */ int qa = q.Numerator.ToInt32(); int qb = q.Denominator.ToInt32(); /* Newton iterations. */ BigDecimal xpowa = PowRound(x, qa); for (;;) { /* numerator and denominator of the Newton term. The major * disadvantage of this implementation is that the updates of the powers * of the new estimate are done in full precision calling BigDecimal.pow(), * which becomes slow if the denominator of q is large. */ BigDecimal nu = res.Pow(qb).Subtract(xpowa); BigDecimal de = MultiplyRound(res.Pow(qb - 1), q.Denominator); /* estimated correction */ BigDecimal eps = nu.Divide(de, MathContext.Decimal64); BigDecimal err = res.Multiply(reserr, MathContext.Decimal64); int precDiv = 2 + ErrorToPrecision(eps, err); if (precDiv <= 0) { /* The case when the precision is already reached and any precision * will do. */ eps = nu.Divide(de, MathContext.Decimal32); } else { eps = nu.Divide(de, new MathContext(precDiv)); } res = SubtractRound(res, eps); /* reached final precision if the relative error fell below reserr, * |eps/res| < reserr */ if (eps.Divide(res, MathContext.Decimal64).Abs().CompareTo(reserr) < 0) { /* delete the bits of extra precision kept in this * working copy. */ return res.Round(new MathContext(ErrorToPrecision(reserr.ToDouble()))); } } } /* The error in x^q is q*x^(q-1)*Delta(x) + Delta(q)*x^q*log(x). * The relative error is q/x*Delta(x) + Delta(q)*log(x). Convert q to a floating point * number such that its relative error becomes negligible: Delta(q)/q << Delta(x)/x/log(x) . */ int precq = 3 + ErrorToPrecision((x.Ulp().Divide(x, MathContext.Decimal64)).ToDouble() /System.Math.Log(x.ToDouble())); /* Perform the actual calculation as exponentiation of two floating point numbers. */ return Pow(x, q.ToBigDecimal(new MathContext(precq))); }
/// <summary> /// Итерация метода ветвей и границ /// </summary> /// <param name="additionalRestrictions">Дополнительные ограничения, вводимые при ветвлении</param> private void Iterate(List <DataRow> additionalRestrictions) { DataTable dt = (dataGridView1.DataSource as DataTable).Copy(); dt.Columns.RemoveAt(0); Dictionary <int, int> rSign = new Dictionary <int, int>(); StringBuilder @string = new StringBuilder(); foreach (var r in additionalRestrictions) { var x = dt.NewRow(); x.ItemArray = r.ItemArray.Clone() as object[]; for (int j = 0; j < r.ItemArray.Length; j++) { if (!(x[j] is DBNull)) { int sgn = Math.Sign(((Rational)x[j]).ToDouble()); if (sgn != 0 && j < x.ItemArray.Length - 1) { rSign.Add(dt.Rows.Count, sgn); @string.AppendFormat(" x{0}{1}{2}", j + 1, sgn > 0 ? '≤' : '≥', Rational.Abs((Rational)x[x.ItemArray.Length - 1])); } x[j] = Rational.Abs((Rational)x[j]); } } dt.Rows.Add(x); } int xcnt = dt.Columns.Count - 1; int scnt = dt.Rows.Count - 1; Rational[,] matrix = new Rational[xcnt + scnt + 2, scnt + 2]; for (int j = 0; j < matrix.GetLength(0); j++) //Столбцы { matrix[j, 0] = j; } for (int i = 1; i < matrix.GetLength(1); i++) //Строки { matrix[0, i] = i == 1 ? 0 : i + xcnt - 1; for (int j = 1; j < matrix.GetLength(0); j++) //Столбцы { if (j < dt.Columns.Count) //Заполним для всех Х { object txx = dt.Rows[i - 1][j - 1]; matrix[j, i] = txx is DBNull ? 0 : (Rational)txx; } else if (matrix[0, i] == matrix[j, 0]) //Для всех S единички по диагонали { matrix[j, i] = rSign.ContainsKey(i) ? rSign[i] : 1; } else if (j == matrix.GetLength(0) - 1) { object txx = dt.Rows[i - 1][dt.Columns.Count - 1]; matrix[j, i] = txx is DBNull ? 0 : (Rational)txx; } else { matrix[j, i] = 0; } } } //PrintMatrix(matrix); textBox1.AppendText(string.Format("\r\nРешение{0}:{1}", @string.ToString(), Environment.NewLine)); Simplex(matrix, checkBox1.Checked); Rational[] result = new Rational[xcnt]; for (int i = 0; i < result.Length; i++) { result[i] = 0; } for (int i = 2; i < matrix.GetLength(1); i++) { if (matrix[0, i] <= xcnt) { result[matrix[0, i].Numerator - 1] = matrix[matrix.GetLength(0) - 1, i]; } } int rIdx = -1; for (int i = 0; i < result.Length; i++) { textBox1.AppendText(string.Format("x{0}={1}{2}", i + 1, result[i].ToMixedString(), i != result.Length - 1 ? "; " : " ")); if (rIdx < 0 && result[i].Denominator > 1) //Дробный корень { rIdx = i; } } textBox1.AppendText(string.Format("z(max)= {2} {0} решение{1}", rIdx < 0 && matrix[matrix.GetLength(0) - 1, 1].Denominator == 1 ? "Целое" : "Дробное", Environment.NewLine, matrix[matrix.GetLength(0) - 1, 1].ToMixedString())); if (rIdx < 0) { if (matrix[matrix.GetLength(0) - 1, 1].Denominator != 1) { textBox1.AppendText("Нет решения" + Environment.NewLine); return; } for (int i = 2; i < dataGridView1.RowCount; i++) { Rational check = 0; for (int j = 1; j < dataGridView1.Columns.Count - 1; j++) { check += (result[j - 1] * (Rational)(dataGridView1[j, i].Value is DBNull ? Rational.Zero : dataGridView1[j, i].Value)); } if (check > (Rational)dataGridView1[dataGridView1.ColumnCount - 1, i].Value) { textBox1.AppendText("Ограничения не выполнены" + Environment.NewLine); return; } } if (checkBox1.Checked == false) { if (matrix[matrix.GetLength(0) - 1, 1] > record[record.Length - 1]) { for (int i = 0; i < record.Length - 1; i++) { record[i] = result[i]; } record[record.Length - 1] = matrix[matrix.GetLength(0) - 1, 1]; } } else { if (matrix[matrix.GetLength(0) - 1, 1] < record[record.Length - 1] || record[record.Length - 1] == 0) { for (int i = 0; i < record.Length - 1; i++) { record[i] = result[i]; } record[record.Length - 1] = matrix[matrix.GetLength(0) - 1, 1]; } } } if (rIdx >= 0 && xcnt > additionalRestrictions.Count) { foreach (var a in additionalRestrictions) { if (!(a[rIdx] is DBNull) && Rational.Abs((Rational)a[rIdx]) == 1) { return; //Уже есть ограничение для этого Х } } additionalRestrictions.Add(dt.NewRow()); additionalRestrictions[additionalRestrictions.Count - 1][rIdx] = Rational.One; additionalRestrictions[additionalRestrictions.Count - 1][dt.Columns.Count - 1] = (Rational)Math.Floor(result[rIdx].ToDouble()); Iterate(additionalRestrictions); additionalRestrictions[additionalRestrictions.Count - 1][rIdx] = -Rational.One; additionalRestrictions[additionalRestrictions.Count - 1][dt.Columns.Count - 1] = -(Rational)Math.Ceiling(result[rIdx].ToDouble()); Iterate(additionalRestrictions); additionalRestrictions.RemoveAt(additionalRestrictions.Count - 1); } }
public void InitializeGrid() { grid = new Dictionary <Tuple <Rational, Rational>, CBNode>(); unprocessedNodeList = new List <CBNode>(); // Create nodes for (Rational m1 = -j1; m1 <= j1; m1 += 1) { for (Rational m2 = -j2; m2 <= j2; m2 += 1) { if (Rational.Abs(m1 + m2) <= j && Rational.Abs(m1) <= j1 && Rational.Abs(m2) <= j2) { var node = new CBNode(m1, m2); if (grid.ContainsKey(node.GridCoordinate)) { throw new Exception("Node already created: m1: " + m1.ToString() + "; m2: " + m2.ToString()); } grid.Add(node.GridCoordinate, node); unprocessedNodeList.Add(node); } } } // Populate neighbors for (Rational m1 = -j1; m1 <= j1; m1 += 1) { for (Rational m2 = -j2; m2 <= j2; m2 += 1) { var coord = new Tuple <Rational, Rational>(m1, m2); if (grid.ContainsKey(coord)) { var node = grid[coord]; var c_m1_00 = new Tuple <Rational, Rational>(m1 - 1, m2); var c_00_m1 = new Tuple <Rational, Rational>(m1, m2 - 1); var c_00_p1 = new Tuple <Rational, Rational>(m1, m2 + 1); var c_p1_00 = new Tuple <Rational, Rational>(m1 + 1, m2); var c_p1_m1 = new Tuple <Rational, Rational>(m1 + 1, m2 - 1); var c_p1_p1 = new Tuple <Rational, Rational>(m1 + 1, m2 + 1); var c_m1_m1 = new Tuple <Rational, Rational>(m1 - 1, m2 - 1); var c_m1_p1 = new Tuple <Rational, Rational>(m1 - 1, m2 + 1); if (grid.ContainsKey(c_m1_00)) { node.n_m1_00 = grid[c_m1_00]; } if (grid.ContainsKey(c_00_m1)) { node.n_00_m1 = grid[c_00_m1]; } if (grid.ContainsKey(c_00_p1)) { node.n_00_p1 = grid[c_00_p1]; } if (grid.ContainsKey(c_p1_00)) { node.n_p1_00 = grid[c_p1_00]; } if (grid.ContainsKey(c_p1_m1)) { node.n_p1_m1 = grid[c_p1_m1]; } if (grid.ContainsKey(c_p1_p1)) { node.n_p1_p1 = grid[c_p1_p1]; } if (grid.ContainsKey(c_m1_m1)) { node.n_m1_m1 = grid[c_m1_m1]; } if (grid.ContainsKey(c_m1_p1)) { node.n_m1_p1 = grid[c_m1_p1]; } } } } // Set the seed node // Looking for a node that only has one non-null neighbor as part of a triangle // Start by trying the maximal m for (Rational m1 = j1; m1 >= -j1; m1 -= 1) { for (Rational m2 = j2; m2 >= -j2; m2 -= 1) { var coord = new Tuple <Rational, Rational>(m1, m2); if (grid.ContainsKey(coord)) { var node = grid[coord]; if ((node.n_m1_00 != null && node.n_00_m1 == null) || (node.n_m1_00 == null && node.n_00_m1 != null) || (node.n_p1_00 != null && node.n_00_p1 == null) || (node.n_p1_00 == null && node.n_00_p1 != null) || (node.n_p1_00 != null && node.n_p1_m1 == null) || (node.n_p1_00 == null && node.n_p1_m1 != null) || (node.n_00_p1 != null && node.n_m1_p1 == null) || (node.n_00_p1 == null && node.n_m1_p1 != null) || (node.n_00_m1 != null && node.n_p1_m1 == null) || (node.n_00_m1 == null && node.n_p1_m1 != null) || (node.n_m1_00 != null && node.n_m1_p1 == null) || (node.n_m1_00 == null && node.n_m1_p1 != null)) { node.rawCoefficient = 1; node.IsSet = true; node.IsSeedNode = true; seedNode = node; break; } } } if (seedNode != null) { break; } } }
/// <summary> /// S = simplest form, R = all under the radical /// </summary> /// <param name="format"></param> /// <param name="formatProvider"></param> /// <returns></returns> public string ToString(string format, IFormatProvider formatProvider) { if (Coefficient.IsZero) { return("0"); } if (Radicand.IsZero) { return("0"); } if (format == null) { format = "S"; } if (IsZero) { return(0.ToString()); } if (IsOne) { return(1.ToString()); } var result = new StringBuilder(); // Simplest form if ("S".Equals(format)) { // Handle coefficient // TODO: Pass format through if (Coefficient.Denominator.IsOne) { if (!Coefficient.Numerator.IsOne || (Coefficient.Numerator.IsOne && Radicand.IsOne)) { if (Sign < 0) { result.Append("(" + Coefficient.Numerator.ToString() + ")"); } else { result.Append(Coefficient.Numerator.ToString()); } } } else { result.Append("(" + Coefficient.ToString() + ")"); } // Handle radicand if (Index > 1 && Radicand > 1) { if (result.Length > 0) { result.Append("*"); } if (Index == 2) { result.Append("Sqrt"); } else { result.Append("Nth-Root[index:" + Index.ToString() + "]"); } result.Append("(" + Radicand.ToString() + ")"); } } else if ("R".Equals(format)) { if (Index == 1) { if (Coefficient.Denominator.IsOne) { if (!Coefficient.Numerator.IsOne || (Coefficient.Numerator.IsOne && Radicand.IsOne)) { result.Append(Coefficient.Numerator.ToString()); } } else { result.Append("(" + Coefficient.ToString() + ")"); } } else { if (Sign < 0) { result.Append("-"); } // Get the rational for all under the radical if (Index == 2) { result.Append("Sqrt"); } else { result.Append("Nth-Root[index:" + Index.ToString() + "]"); } var radicand = RaisedToIndexPower; if (radicand.Denominator.IsOne) { result.Append("(" + BigInteger.Abs(radicand.Numerator).ToString() + ")"); } else { result.Append("(" + Rational.Abs(radicand.CanonicalForm).ToString() + ")"); } } } return(result.ToString()); }
// j1 // j2 // m1 // m2 // j // m // m1 + m2 = m +- 1 // abs(m1) <= j1 // abs(m2) <= j2 // -j <= m1 + m2 <= j // sqrt[(j -+ m)(j +- m + 1)]<m1, m2; j, m +- 1> // = sqrt[(j1 -+ m1 + 1)(j1 +- m1)]<m1 -+ 1, m2; j, m> // + sqrt[(j2 -+ m2 + 1)(j2 +- m2)]<m1, m2 -+ 1; j, m> // Fix j1, j2, j // J+: // sqrt[(j - m)(j + m + 1)]<m1, m2; j, m + 1> // = sqrt[(j1 - m1 + 1)(j1 + m1)]<m1 - 1, m2; j, m> // + sqrt[(j2 - m2 + 1)(j2 + m2)]<m1, m2 - 1; j, m> // ; m1 + m2 = m + 1 // J-: // sqrt[(j + m)(j - m + 1)]<m1, m2; j, m - 1> // = sqrt[(j1 + m1 + 1)(j1 - m1)]<m1 + 1, m2; j, m> // + sqrt[(j2 + m2 + 1)(j2 - m2)]<m1, m2 + 1; j, m> // ; m1 + m2 = m - 1 // J+: // <m1, m2; j, m + 1> = {sqrt[(j1 - m1 + 1)(j1 + m1)]<m1 - 1, m2; j, m> + sqrt[(j2 - m2 + 1)(j2 + m2)]<m1, m2 - 1; j, m>} / sqrt[(j - m)(j + m + 1)] // <m1 - 1, m2; j, m> = {sqrt[(j - m)(j + m + 1)]<m1, m2; j, m + 1> - sqrt[(j2 - m2 + 1)(j2 + m2)]<m1, m2 - 1; j, m>} / sqrt[(j1 - m1 + 1)(j1 + m1)] // <m1, m2 - 1; j, m> = {sqrt[(j - m)(j + m + 1)]<m1, m2; j, m + 1> - sqrt[(j1 - m1 + 1)(j1 + m1)]<m1 - 1, m2; j, m>} / sqrt[(j2 - m2 + 1)(j2 + m2)] // J-: // <m1, m2; j, m - 1> = {sqrt[(j1 + m1 + 1)(j1 - m1)]<m1 + 1, m2; j, m> + sqrt[(j2 + m2 + 1)(j2 - m2)]<m1, m2 + 1; j, m>} / sqrt[(j + m)(j - m + 1)] // <m1 + 1, m2; j, m> = {sqrt[(j + m)(j - m + 1)]<m1, m2; j, m - 1> - sqrt[(j2 + m2 + 1)(j2 - m2)]<m1, m2 + 1; j, m>} / sqrt[(j1 + m1 + 1)(j1 - m1)] // <m1, m2 + 1; j, m> = {sqrt[(j + m)(j - m + 1)]<m1, m2; j, m - 1> - sqrt[(j1 + m1 + 1)(j1 - m1)]<m1 + 1, m2; j, m>} / sqrt[(j2 + m2 + 1)(j2 - m2)] static void Main(string[] args) { bool continueProgram = true; while (continueProgram) { bool isValidInput = false; Rational j1 = 0; Rational j2 = 0; Rational j = 0; Rational m1 = 0; Rational m2 = 0; Rational m = 0; while (!isValidInput) { Console.Write("j1: "); j1 = Rational.Parse(Console.ReadLine()); Console.Write("j2: "); j2 = Rational.Parse(Console.ReadLine()); Console.Write("m: "); m = Rational.Parse(Console.ReadLine()); Console.Write("j: "); j = Rational.Parse(Console.ReadLine()); Console.Write("m1: "); m1 = Rational.Parse(Console.ReadLine()); Console.Write("m2: "); m2 = Rational.Parse(Console.ReadLine()); if (Rational.Abs(j1 - j2) > j || j > j1 + j2) { Console.WriteLine("Parameters violate |j1 - j2| <= j <= j1 + j2"); } else if (m1 + m2 != m) { Console.WriteLine("Parameters violate m1 + m2 = m"); } else if (Rational.Abs(m1) > j1) { Console.WriteLine("Parameters violate |m1| <= j1"); } else if (Rational.Abs(m2) > j2) { Console.WriteLine("Parameters violate |m2| <= j2"); } else if (Rational.Abs(m1 + m2) > j) { Console.WriteLine("Parameters violate -j <= m1 + m2 <= j"); } else if (j1.Denominator != m1.Denominator) { Console.WriteLine("Parameters violate j1 and m1 must both simultaneously be integers or half integers"); } else if (j2.Denominator != m2.Denominator) { Console.WriteLine("Parameters violate j2 and m2 must both simultaneously be integers or half integers"); } else { isValidInput = true; } } // Run the scenario CBScenario scenario = new CBScenario(j1: j1, j2: j2, j: j, m: m); scenario.InitializeGrid(); if (scenario.seedNode == null) { Console.Write("-----SEED NODE NOT SET-----"); } scenario.CalculateRawCoefficients(); scenario.NormalizeCoefficients(); //Utilities.DrawGrid(scenario); var node = scenario.grid[new Tuple <Rational, Rational>(m1, m2)]; Console.WriteLine("Requested coefficient: " + node.ToString()); Console.WriteLine("Run another scenario? (y/n)"); var input = Console.ReadLine(); if ("y".Equals(input, StringComparison.InvariantCultureIgnoreCase) || "yes".Equals(input, StringComparison.InvariantCultureIgnoreCase)) { continue; } else { continueProgram = false; } } }