Beispiel #1
0
        /// <summary>
        /// If this FunctionGenerator can implement 'F', then this function should complete the (possible)
        /// blanks in 'F'. This means:
        ///  - Fill in F.m_returnTypeName if it is empty
        ///  - Fill in F.m_argumentTypeNames (and m_argumentVariableNames) if it is empty.
        /// </summary>
        public override void CompleteFGS()
        {
            m_ipType = GetIpType(m_specification, m_fgs);

            // fill in ArgumentTypeNames
            if (m_fgs.ArgumentTypeNames.Length == 0)
            {
                m_fgs.m_argumentTypeNames = new String[] { m_gmv.Name, m_gmv.Name }
            }
            ;

            // init argument pointers from the completed typenames (language sensitive);
            m_fgs.InitArgumentPtrFromTypeNames(m_specification);

            // get all function info
            FloatType FT = m_specification.GetFloatType(m_fgs.FloatNames[0]);
            bool      computeMultivectorValue = true;

            G25.CG.Shared.FuncArgInfo[] tmpFAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, m_specification.m_GMV.Name, computeMultivectorValue);

            m_gmvFunc = !(tmpFAI[0].IsScalarOrSMV() && tmpFAI[1].IsScalarOrSMV());
            m_smv1    = tmpFAI[0].Type as G25.SMV;
            m_smv2    = tmpFAI[1].Type as G25.SMV;

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                if (m_ipType != RefGA.BasisBlade.InnerProductType.SCALAR_PRODUCT)
                {
                    m_fgs.m_returnTypeName = m_gmv.Name;// gmv * gmv = gmv
                }
                else
                {
                    m_fgs.ReturnTypeName = FT.type;
                }
            }
            else
            {
                // compute return value
                m_returnValue = RefGA.Multivector.ip(tmpFAI[0].MultivectorValue[0], tmpFAI[1].MultivectorValue[0], m_M, m_ipType);

                // round value if required by metric
                if (m_G25M.m_round)
                {
                    m_returnValue = m_returnValue.Round(1e-14);
                }

                // get name of return type
                if ((m_fgs.ReturnTypeName.Length == 0) && (m_ipType != RefGA.BasisBlade.InnerProductType.SCALAR_PRODUCT))
                {
                    m_fgs.ReturnTypeName = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue).GetName();
                }
                else
                {
                    m_fgs.ReturnTypeName = FT.type;
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// If this FunctionGenerator can implement 'F', then this function should complete the (possible)
        /// blanks in 'F'. This means:
        ///  - Fill in F.m_returnTypeName if it is empty
        ///  - Fill in F.m_argumentTypeNames (and m_argumentVariableNames) if it is empty.
        /// </summary>
        public override void CompleteFGS()
        {
            m_ipType = GetIpType(m_specification, m_fgs);

            // fill in ArgumentTypeNames
            if (m_fgs.ArgumentTypeNames.Length == 0)
                m_fgs.m_argumentTypeNames = new String[] { m_gmv.Name, m_gmv.Name };

            // init argument pointers from the completed typenames (language sensitive);
            m_fgs.InitArgumentPtrFromTypeNames(m_specification);

            // get all function info
            FloatType FT = m_specification.GetFloatType(m_fgs.FloatNames[0]);
            bool computeMultivectorValue = true;
            G25.CG.Shared.FuncArgInfo[] tmpFAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, m_specification.m_GMV.Name, computeMultivectorValue);

            m_gmvFunc = !(tmpFAI[0].IsScalarOrSMV() && tmpFAI[1].IsScalarOrSMV());
            m_smv1 = tmpFAI[0].Type as G25.SMV;
            m_smv2 = tmpFAI[1].Type as G25.SMV;

            // compute intermediate results, set return type
            if (m_gmvFunc)
            {
                if (m_ipType != RefGA.BasisBlade.InnerProductType.SCALAR_PRODUCT)
                {
                    m_fgs.m_returnTypeName = m_gmv.Name;// gmv * gmv = gmv
                }
                else
                {
                    m_fgs.ReturnTypeName = FT.type;
                }
            }
            else
            {
                // compute return value
                m_returnValue = RefGA.Multivector.ip(tmpFAI[0].MultivectorValue[0], tmpFAI[1].MultivectorValue[0], m_M, m_ipType);

                // round value if required by metric
                if (m_G25M.m_round) m_returnValue = m_returnValue.Round(1e-14);

                // get name of return type
                if ((m_fgs.ReturnTypeName.Length == 0) && (m_ipType != RefGA.BasisBlade.InnerProductType.SCALAR_PRODUCT))
                {
                    m_fgs.ReturnTypeName = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue).GetName();
                }
                else
                {
                    m_fgs.ReturnTypeName = FT.type;
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// If this FunctionGenerator can implement 'F', then this function should complete the (possible)
        /// blanks in 'F'. This means:
        ///  - Fill in F.m_returnTypeName if it is empty
        ///  - Fill in F.m_argumentTypeNames (and m_argumentVariableNames) if it is empty.
        ///
        /// As the return type is required, many functions will also compute the return value and other info
        /// needed for generating the code inside this function. These intermediate values are then
        /// stored in class variables so they can be reused in WriteFunction()
        /// </summary>
        public override void CompleteFGS()
        {
            NB_ARGS = m_fgs.NbArguments; // all arguments must be explicitly listed

            // init argument pointers from the completed typenames (language sensitive);
            m_fgs.InitArgumentPtrFromTypeNames(m_specification);

            // get all function info
            FloatType FT = m_specification.GetFloatType(m_fgs.FloatNames[0]);
            bool      computeMultivectorValue = true;

            G25.CG.Shared.FuncArgInfo[] tmpFAI = G25.CG.Shared.FuncArgInfo.GetAllFuncArgInfo(m_specification, m_fgs, NB_ARGS, FT, m_specification.m_GMV.Name, computeMultivectorValue);

            { // compute return value
                RefGA.Multivector no = GetOrigin(m_specification, m_fgs);
                RefGA.Multivector ni = GetInfinity(m_specification, m_fgs);

                // compose a vector value (the Euclidean part)
                RefGA.Multivector vectorValue = RefGA.Multivector.ZERO;
                if ((IsRandom(m_specification, m_fgs)) || (IsCoordBased(m_specification, m_fgs, FT)))
                {
                    m_returnValue = no;
                    for (int i = 0; i < m_specification.m_dimension - 2; i++)
                    {
                        string bvName = "e" + (i + 1).ToString(); // todo: this assumes a fixed name for the basis vectors. Make these names options?
                        int    bvIdx  = m_specification.GetBasisVectorIndex(bvName);
                        if (bvIdx < 0)
                        {
                            throw new G25.UserException("Cannot find basis vector " + bvName, XML.FunctionToXmlString(m_specification, m_fgs));
                        }

                        RefGA.Multivector basisVector = RefGA.Multivector.GetBasisVector(bvIdx);

                        if (IsRandom(m_specification, m_fgs))
                        {
                            vectorValue = RefGA.Multivector.Add(vectorValue, RefGA.Multivector.gp(new RefGA.Multivector("ce" + (i + 1).ToString()), basisVector));
                        }
                        else
                        {
                            vectorValue = RefGA.Multivector.Add(vectorValue, RefGA.Multivector.gp(tmpFAI[i].MultivectorValue[0], basisVector));
                        }
                    }
                }
                else if (IsVectorBased(m_specification, m_fgs, FT))
                {
                    vectorValue  = tmpFAI[0].MultivectorValue[0];
                    m_vectorType = tmpFAI[0].Type;
                }
                else if (IsFlatPointBased(m_specification, m_fgs, FT))
                {
                    m_flatPointType = tmpFAI[0].Type as G25.SMV;
                    RefGA.BasisBlade.InnerProductType lc = RefGA.BasisBlade.InnerProductType.LEFT_CONTRACTION;
                    RefGA.Multivector noni = RefGA.Multivector.OuterProduct(no, ni);
                    // scale = no^ni . pointPair
                    RefGA.Multivector scale =
                        RefGA.Multivector.InnerProduct(noni, tmpFAI[0].MultivectorValue[0], m_M, lc).ScalarPart();
                    if (m_G25M.m_round)
                    {
                        scale = scale.Round(1e-14);
                    }

                    // sphere = no . pointPair
                    RefGA.Multivector sphere = RefGA.Multivector.InnerProduct(no, tmpFAI[0].MultivectorValue[0], m_M, lc);
                    // normalizedSphere = sphere / scale

                    bool needToNormalize = (scale.HasSymbolicScalars() || (scale.RealScalarPart() != 1.0));
                    RefGA.Multivector normalizedSphere = (needToNormalize) ? RefGA.Multivector.gp(sphere, RefGA.Symbolic.UnaryScalarOp.Inverse(scale)) : sphere;

                    // keep only euclidean vectors
                    RefGA.Multivector euclMultivector = getSumOfUnitEuclideanBasisVectors();
                    // vector = sphere-noni
                    m_pointPairVectorValue = RefGA.Multivector.hp(normalizedSphere, euclMultivector);
                    // round vector
                    if (m_G25M.m_round)
                    {
                        m_pointPairVectorValue = m_pointPairVectorValue.Round(1e-14);
                    }

                    // get type
                    m_vectorType = (G25.SMV)G25.CG.Shared.SpecializedReturnType.FindTightestMatch(m_specification, m_pointPairVectorValue, FT);
                    if (m_vectorType == null)
                    {
                        throw new G25.UserException("Missing Euclidean vector type; cannot construct conformal point from " + m_fgs.ArgumentTypeNames[0], XML.FunctionToXmlString(m_specification, m_fgs));
                    }

                    // get 'value' (just a reference to the name of the variable where m_pointPairVectorValue will be stored.
                    bool pointer = false;
                    vectorValue = Symbolic.SMVtoSymbolicMultivector(m_specification, (G25.SMV)m_vectorType, VECTOR_NAME, pointer);
                }
                else
                {
                    throw new G25.UserException("Invalid arguments specified.", XML.FunctionToXmlString(m_specification, m_fgs));
                }

                { // add no and 0.5 vectorValue^2 ni
                    RefGA.Multivector vectorValueSquared = RefGA.Multivector.scp(vectorValue, vectorValue);
                    RefGA.Multivector niPart             = RefGA.Multivector.gp(
                        RefGA.Multivector.gp(vectorValueSquared, ni), 0.5);
                    m_returnValue = RefGA.Multivector.Add(RefGA.Multivector.Add(no, vectorValue), niPart);
                }
            } // end of compute return value

            // get name of return type
            if (m_fgs.m_returnTypeName.Length == 0)
            {
                m_fgs.m_returnTypeName = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue).GetName();
            }
        } // end of CompleteFGS()