private void AddRulesFromSingleLinearCombination <TVertex>(LinearCombination <Path <TVertex> > linComb, TransformationRuleTreeNode <TVertex> root)
            where TVertex : IEquatable <TVertex>, IComparable <TVertex>
        {
            switch (linComb.ElementToCoefficientDictionary.Count)
            {
            case 0: return;

            case 1:
                var path = linComb.Elements.Single();
                var node = GetOrInsertDefaultNode(path, root);
                node.CanBeKilled = true;
                break;

            case 2:
                var coefficients = linComb.ElementToCoefficientDictionary.Values.ToList();
                var paths        = linComb.Elements.ToList(); // Could be in different order from the coefficients, but don't care
                if (coefficients[1] == -coefficients[0])
                {
                    GetOrInsertDefaultNode(paths[0], root).ReplacementPath = paths[1];
                    GetOrInsertDefaultNode(paths[1], root).ReplacementPath = paths[0];
                }
                else
                {
                    throw new NotSupportedException("Linear combinations of length 2 with coefficients that are not the additive inverse of each other are not supported.");
                }
                break;

            default:
                throw new NotSupportedException("Linear combinations of length greater than 2 are not supported.");
            }
        }
Exemplo n.º 2
0
        public void NeqOperator_OnNull()
        {
            LinearCombination <char> nullComb = null;
            var comb = CreateComb(new KeyValuePair <char, int>('a', 1), new KeyValuePair <char, int>('b', 2));

            Assert.That(nullComb != null, Is.False);
            Assert.That(comb != null, Is.True);
        }
Exemplo n.º 3
0
        public void Constructor_InitializesElementToCoefficientDictionaryWithoutZeros()
        {
            var dict = new Dictionary <char, int>
            {
                { 'a', 0 },
                { 'b', 1 },
                { 'c', 2 },
                { 'd', -0 },
                { 'e', 3 },
                { 'f', 0 },
            };
            var expectedDict = new Dictionary <char, int>
            {
                { 'b', 1 },
                { 'c', 2 },
                { 'e', 3 },
            };

            var comb = new LinearCombination <char>(dict);

            Assert.That(comb.ElementToCoefficientDictionary, Is.EqualTo(expectedDict));
        }
        /// <remarks>This method should be made obsolete (prefer converting the QP to a
        /// semimonomial unbound quiver, and analyzing that instead (or at least creating the
        /// transformation rule tree for that instead).</remarks>
        public TransformationRuleTreeNode <TVertex> CreateTransformationRuleTree <TVertex>(QuiverWithPotential <TVertex> qp)
            where TVertex : IEquatable <TVertex>, IComparable <TVertex>
        {
            if (qp is null)
            {
                throw new ArgumentNullException(nameof(qp));
            }

            var root = new TransformationRuleTreeNode <TVertex>(false, null, null);

            foreach (var arrow in qp.Quiver.Arrows)
            {
                var linComb = new LinearCombination <Path <TVertex> >();
                foreach (var(cycle, coefficient) in qp.Potential.LinearCombinationOfCycles.ElementToCoefficientDictionary)
                {
                    linComb = linComb.Add(cycle.DifferentiateCyclically(arrow).Scale(coefficient));
                }

                AddRulesFromSingleLinearCombination(linComb, root);
            }

            return(root);
        }
Exemplo n.º 5
0
 private static IEnumerable <LinearCombination> Factor(IEnumerable <LinearCombination> x)
 {
     return(x.Select(i => LinearCombination.New(i.Select(j => new KeyValuePair <Expression, Expression>(j.Key, j.Value.Factor())))).Buffer());
 }
Exemplo n.º 6
0
        static void Main(string[] args)
        {
            // This QuickStart sample illustrates linear least squares
            // curve fitting using polynomials and linear combinations
            // of arbitrary functions.

            // Linear least squares fits are calculated using the
            // LinearCurveFitter class:
            LinearCurveFitter fitter = new LinearCurveFitter();

            // We use data from the National Institute for Standards
            // and Technology's Statistical Reference Datasets library
            // at http://www.itl.nist.gov/div898/strd/.

            // Note that, due to round-off error, the results here will not be exactly
            // the same as the NIST results, which were calculated using 500 digits
            // of precision!

            // We use the 'Pontius' dataset, which contains measurement data
            // from the calibration of load cells. The independent variable is the load.
            // The dependent variable is the deflection.
            var deflectionData = Vector.Create(.11019, .21956,
                                               .32949, .43899, .54803, .65694, .76562, .87487, .98292,
                                               1.09146, 1.20001, 1.30822, 1.41599, 1.52399, 1.63194, 1.73947,
                                               1.84646, 1.95392, 2.06128, 2.16844, .11052, .22018, .32939,
                                               .43886, .54798, .65739, .76596, .87474, .98300, 1.09150, 1.20004,
                                               1.30818, 1.41613, 1.52408, 1.63159, 1.73965,
                                               1.84696, 1.95445, 2.06177, 2.16829);
            var loadData = Vector.Create(
                150.0, 300, 450, 600, 750, 900,
                1050, 1200, 1350, 1500, 1650, 1800,
                1950, 2100, 2250, 2400, 2550, 2700,
                2850, 3000, 150, 300, 450, 600,
                750, 900, 1050, 1200, 1350, 1500,
                1650, 1800, 1950, 2100, 2250, 2400,
                2550, 2700, 2850, 3000);

            // You must supply the curve whose parameters will be
            // fit to the data. The curve must inherit from LinearCombination.
            //
            // Here, we use a quadratic polynomial:
            fitter.Curve = new Polynomial(2);

            // The X values go into the XValues property:
            fitter.XValues = loadData;
            // ...and Y values go into the YValues property:
            fitter.YValues = deflectionData;

            // The Fit method performs the actual calculation:
            fitter.Fit();

            // A var containing the parameters of the best fit
            // can be obtained through the
            // BestFitParameters property.
            var solution = fitter.BestFitParameters;
            // The standard deviations associated with each parameter
            // are available through the GetStandardDeviations method.
            var s = fitter.GetStandardDeviations();

            Console.WriteLine("Calibration of load cells");
            Console.WriteLine("    deflection = c1 + c2*load + c3*load^2 ");
            Console.WriteLine("Solution:");
            Console.WriteLine("c1: {0,20:E10} {1,20:E10}", solution[0], s[0]);
            Console.WriteLine("c2: {0,20:E10} {1,20:E10}", solution[1], s[1]);
            Console.WriteLine("c3: {0,20:E10} {1,20:E10}", solution[2], s[2]);

            Console.WriteLine("Residual sum of squares: {0}", fitter.Residuals.Norm());

            // Now let's redo the same operation, but with observations weighted
            // by 1/Y^2. To do this, we set the WeightFunction property.
            // The WeightFunctions class defines a set of ready-to-use weight functions.
            fitter.WeightFunction = WeightFunctions.OneOverYSquared;
            // Refit the curve:
            fitter.Fit();
            solution = fitter.BestFitParameters;
            s        = fitter.GetStandardDeviations();

            // The solution is slightly different:
            Console.WriteLine("Solution (weighted observations):");
            Console.WriteLine("c1: {0,20:E10} {1,20:E10}", solution[0], s[0]);
            Console.WriteLine("c2: {0,20:E10} {1,20:E10}", solution[1], s[1]);
            Console.WriteLine("c3: {0,20:E10} {1,20:E10}", solution[2], s[2]);
            Console.WriteLine();

            //
            // Fitting combinations of arbitrary functions
            //

            // The following example estimates the two parameters, c1 and c2
            // in the theoretical model for conductance:
            //     k(T) = 1 / (c1 / T + c2 * T*T)

            var temperature = Vector.Create(12.2900, 13.7500, 14.8200,
                                            16.1200, 18.0400, 18.6700, 20.5200, 22.6800, 25.1500,
                                            27.7200, 30.2400, 33.2100, 36.4800, 39.8600, 50.4000);
            var conductance = Vector.Create(25.3500, 27.8800, 29.9300,
                                            30.4200, 31.0000, 31.9600, 32.4700, 30.3300, 31.1400,
                                            27.4600, 23.2900, 20.7200, 17.2400, 14.7100, 9.5000);

            // First, we transform the dependent variable:
            var y = Vector.Reciprocal(conductance);

            // y is a linear combination of basis functions 1/T and T*T.
            // Create a function basis object:
            Func <double, double>[] basisFunctions = new Func <double, double>[] { new Func <double, double>(f1), new Func <double, double>(f2) };
            GeneralFunctionBasis    basis          = new GeneralFunctionBasis(basisFunctions);

            // Create a LinearCombination curve using this function basis:
            LinearCombination curve = new LinearCombination(basis);

            // Set the curve fitter properties:
            fitter.Curve   = curve;
            fitter.XValues = temperature;
            fitter.YValues = y;
            // Reset the weights
            fitter.WeightFunction = null;
            fitter.WeightVector   = null;

            // Now compute the solution:
            fitter.Fit();
            solution = fitter.BestFitParameters;
            s        = fitter.GetStandardDeviations();

            // Print the results
            Console.WriteLine("Conductance of copper: k(T) = 1 / (c1/T + c2*T^2)");
            Console.WriteLine("Solution:");
            Console.WriteLine("c1: {0,20:E10} {1,20:E10}", solution[0], s[0]);
            Console.WriteLine("c2: {0,20:E10} {1,20:E10}", solution[1], s[1]);

            Console.WriteLine("Residual sum of squares: {0}", fitter.Residuals.Norm());

            Console.Write("Press Enter key to exit...");
            Console.ReadLine();
        }