Пример #1
0
        public static Operand CalculateJoin(List <Operand> operandList, Context context)
        {
            OuterProduct[] bladeArray = new OuterProduct[operandList.Count];

            int j = -1;

            for (int i = 0; i < bladeArray.Length; i++)
            {
                try
                {
                    bladeArray[i] = FactorBlade.Factor(operandList[i], context);

                    if (j < 0 || bladeArray[i].Grade > bladeArray[j].Grade)
                    {
                        j = i;
                    }
                }
                catch (MathException exc)
                {
                    throw new MathException($"Failed to factor argument {i} as blade.", exc);
                }
            }

            OuterProduct join = bladeArray[j];

            for (int i = 0; i < bladeArray.Length; i++)
            {
                if (i != j)
                {
                    foreach (Operand vector in bladeArray[i].operandList)
                    {
                        Operand operand = Operand.ExhaustEvaluation(new Trim(new List <Operand>()
                        {
                            new OuterProduct(new List <Operand>()
                            {
                                vector.Copy(), join.Copy()
                            })
                        }), context);
                        if (!operand.IsAdditiveIdentity)
                        {
                            join.operandList.Add(vector);
                        }
                    }
                }
            }

            return(join);
        }
Пример #2
0
        // The algorithm implemented here comes straight out of Christian Perwass' book.
        // TODO: Also, as noted by Perwass, this algorithm doesn't work for null versors.
        public static GeometricProduct Factor(Operand operand, Context context)
        {
            Operand          currentVersor       = operand.Copy();
            GeometricProduct versorFactorization = new GeometricProduct();

            while (true)
            {
                HashSet <int> gradeSet = DiscoverGrades(currentVersor, context);
                int           maxGrade = gradeSet.ToList().Aggregate(0, (currentMaxGrade, grade) => grade > currentMaxGrade ? grade : currentMaxGrade);
                if (maxGrade <= 0)
                {
                    break;
                }

                Operand blade = Operand.ExhaustEvaluation(new GradePart(new List <Operand>()
                {
                    currentVersor.Copy(), new NumericScalar(maxGrade)
                }), context);
                OuterProduct bladeFactorization = null;

                try
                {
                    bladeFactorization = FactorBlade.Factor(blade, context);
                }
                catch (MathException exc)
                {
                    throw new MathException("Highest-grade-part of multivector does not factor as a blade.", exc);
                }

                Operand nonNullVector = null, magnitude = null;

                foreach (Operand vector in bladeFactorization.operandList)
                {
                    if (vector.Grade == 1)
                    {
                        magnitude = Operand.ExhaustEvaluation(new Trim(new List <Operand>()
                        {
                            new Magnitude(new List <Operand>()
                            {
                                vector.Copy()
                            })
                        }), context);
                        if (!magnitude.IsAdditiveIdentity)
                        {
                            nonNullVector = vector;
                            break;
                        }
                    }
                }

                if (nonNullVector == null)
                {
                    throw new MathException("Failed to find non-null vector in blade factorization.");
                }

                Operand unitVector = Operand.ExhaustEvaluation(new Normalize(new List <Operand>()
                {
                    nonNullVector
                }), context);

                versorFactorization.operandList.Insert(0, unitVector);

                currentVersor = Operand.ExhaustEvaluation(new Trim(new List <Operand>()
                {
                    new GeometricProduct(new List <Operand>()
                    {
                        currentVersor, unitVector.Copy()
                    })
                }), context);
            }

            versorFactorization.operandList.Add(currentVersor);

            return(versorFactorization);
        }