/// <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() { // fill in ArgumentTypeNames if (m_fgs.ArgumentTypeNames.Length == 0) { if (m_specification.m_GOM == null) { throw new G25.UserException("No general outermorphism type defined, while it is required because the type of the first argument was unspecified."); } m_fgs.m_argumentTypeNames = new String[] { m_specification.m_GOM.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_om = (G25.OM)tmpFAI[0].Type; m_mv = (G25.MV)tmpFAI[1].Type; m_gmvFunc = !tmpFAI[1].IsScalarOrSMV(); // compute intermediate results, set return type if (m_gmvFunc) { m_fgs.m_returnTypeName = m_gmv.Name; // gmv + gmv = gmv } else { RefGA.Multivector inputValue = tmpFAI[1].MultivectorValue[0]; // Compute m_returnValue: // Replace each basis blade in 'inputValue' with its value under the outermorphism. m_returnValue = RefGA.Multivector.ZERO; for (int i = 0; i < inputValue.BasisBlades.Length; i++) { // get input blade and domain for that grade RefGA.BasisBlade inputBlade = inputValue.BasisBlades[i]; RefGA.BasisBlade[] domainBlades = m_om.DomainForGrade(inputBlade.Grade()); for (int c = 0; c < domainBlades.Length; c++) { // if a match is found in the domain, add range vector to m_returnValue if (domainBlades[c].bitmap == inputBlade.bitmap) { bool ptr = m_specification.OutputC(); RefGA.Multivector omColumnValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(m_specification, m_om.DomainSmvForGrade(inputBlade.Grade())[c], tmpFAI[0].Name, ptr); RefGA.Multivector inputBladeScalarMultiplier = new RefGA.Multivector(new RefGA.BasisBlade(inputBlade, 0)); RefGA.Multivector domainBladeScalarMultiplier = new RefGA.Multivector(new RefGA.BasisBlade(domainBlades[c], 0)); m_returnValue = RefGA.Multivector.Add(m_returnValue, RefGA.Multivector.gp( RefGA.Multivector.gp(omColumnValue, inputBladeScalarMultiplier), domainBladeScalarMultiplier)); break; // no need to search the other domainBlades too } } } // 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(); } } }
/// <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() { // get info on # arguments m_isUnit = IsApplyUnitVersor(m_fgs) || IsApplyVersorWI(m_fgs); // unit or inverse provided? NB_ARGS = GetNbArgs(m_fgs); // number of arguments (2 or 3) // fill in ArgumentTypeNames if (m_fgs.ArgumentTypeNames.Length == 0) { m_fgs.m_argumentTypeNames = new String[NB_ARGS]; for (int i = 0; i < NB_ARGS; i++) { m_fgs.m_argumentTypeNames[i] = 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_versorMv = (G25.MV)tmpFAI[0].Type; m_subjectMv = (G25.MV)tmpFAI[1].Type; if (tmpFAI.Length > 2) { m_inverseVersorMv = (G25.MV)tmpFAI[2].Type; } { // get symbolic result // get grade of input blade: m_inputGradeUsage = tmpFAI[1].MultivectorValue[0].GradeUsage(); // get basic transformed value m_versorValue = tmpFAI[0].MultivectorValue[0]; m_reverseVersorValue = (IsApplyVersorWI(m_fgs)) ? tmpFAI[2].MultivectorValue[0] : RefGA.Multivector.Reverse(m_versorValue); m_transformedValue = RefGA.Multivector.gp( RefGA.Multivector.gp(m_versorValue, tmpFAI[1].MultivectorValue[0], m_M), m_reverseVersorValue, m_M); // apply grade part selection m_transformedValue = m_transformedValue.ExtractGrade(RefGA.Multivector.GradeBitmapToArray(m_inputGradeUsage)); // if rotor is not guaranteed by the user to be unit, compute norm squared if (!m_isUnit) { m_n2Value = RefGA.Multivector.ip(m_reverseVersorValue, m_versorValue, m_M, RefGA.BasisBlade.InnerProductType.LEFT_CONTRACTION); } // round value if required by metric if (m_G25M.m_round) { m_transformedValue = m_transformedValue.Round(1e-14); if (m_n2Value != null) { m_n2Value = m_n2Value.Round(1e-14); } } } // compute intermediate results, set return type if (m_gmvFunc) { m_fgs.m_returnTypeName = m_gmv.Name; // gmv * gmv / gmv = gmv } else { // 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_transformedValue).GetName(); } } m_returnType = m_specification.GetType(m_fgs.m_returnTypeName); }
/// <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() { // get info on # arguments m_isUnit = IsApplyUnitVersor(m_fgs) || IsApplyVersorWI(m_fgs); // unit or inverse provided? NB_ARGS = GetNbArgs(m_fgs); // number of arguments (2 or 3) // fill in ArgumentTypeNames if (m_fgs.ArgumentTypeNames.Length == 0) { m_fgs.m_argumentTypeNames = new String[NB_ARGS]; for (int i = 0; i < NB_ARGS; i++) m_fgs.m_argumentTypeNames[i] = 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_versorMv = (G25.MV)tmpFAI[0].Type; m_subjectMv = (G25.MV)tmpFAI[1].Type; if (tmpFAI.Length > 2) m_inverseVersorMv = (G25.MV)tmpFAI[2].Type; { // get symbolic result // get grade of input blade: m_inputGradeUsage = tmpFAI[1].MultivectorValue[0].GradeUsage(); // get basic transformed value m_versorValue = tmpFAI[0].MultivectorValue[0]; m_reverseVersorValue = (IsApplyVersorWI(m_fgs)) ? tmpFAI[2].MultivectorValue[0] : RefGA.Multivector.Reverse(m_versorValue); m_transformedValue = RefGA.Multivector.gp( RefGA.Multivector.gp(m_versorValue, tmpFAI[1].MultivectorValue[0], m_M), m_reverseVersorValue, m_M); // apply grade part selection m_transformedValue = m_transformedValue.ExtractGrade(RefGA.Multivector.GradeBitmapToArray(m_inputGradeUsage)); // if rotor is not guaranteed by the user to be unit, compute norm squared if (!m_isUnit) m_n2Value = RefGA.Multivector.ip(m_reverseVersorValue, m_versorValue, m_M, RefGA.BasisBlade.InnerProductType.LEFT_CONTRACTION); // round value if required by metric if (m_G25M.m_round) { m_transformedValue = m_transformedValue.Round(1e-14); if (m_n2Value != null) m_n2Value = m_n2Value.Round(1e-14); } } // compute intermediate results, set return type if (m_gmvFunc) m_fgs.m_returnTypeName = m_gmv.Name; // gmv * gmv / gmv = gmv else { // 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_transformedValue).GetName(); } m_returnType = m_specification.GetType(m_fgs.m_returnTypeName); }
/// <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() { // fill in ArgumentTypeNames if (m_fgs.ArgumentTypeNames.Length == 0) { if (m_specification.m_GOM == null) throw new G25.UserException("No general outermorphism type defined, while it is required because the type of the first argument was unspecified."); m_fgs.m_argumentTypeNames = new String[] { m_specification.m_GOM.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_om = (G25.OM)tmpFAI[0].Type; m_mv = (G25.MV)tmpFAI[1].Type; m_gmvFunc = !tmpFAI[1].IsScalarOrSMV(); // compute intermediate results, set return type if (m_gmvFunc) m_fgs.m_returnTypeName = m_gmv.Name;// gmv + gmv = gmv else { RefGA.Multivector inputValue = tmpFAI[1].MultivectorValue[0]; // Compute m_returnValue: // Replace each basis blade in 'inputValue' with its value under the outermorphism. m_returnValue = RefGA.Multivector.ZERO; for (int i = 0; i < inputValue.BasisBlades.Length; i++) { // get input blade and domain for that grade RefGA.BasisBlade inputBlade = inputValue.BasisBlades[i]; RefGA.BasisBlade[] domainBlades = m_om.DomainForGrade(inputBlade.Grade()); for (int c = 0; c < domainBlades.Length; c++) { // if a match is found in the domain, add range vector to m_returnValue if (domainBlades[c].bitmap == inputBlade.bitmap) { bool ptr = m_specification.OutputC(); RefGA.Multivector omColumnValue = G25.CG.Shared.Symbolic.SMVtoSymbolicMultivector(m_specification, m_om.DomainSmvForGrade(inputBlade.Grade())[c], tmpFAI[0].Name, ptr); RefGA.Multivector inputBladeScalarMultiplier = new RefGA.Multivector(new RefGA.BasisBlade(inputBlade, 0)); RefGA.Multivector domainBladeScalarMultiplier = new RefGA.Multivector(new RefGA.BasisBlade(domainBlades[c], 0)); m_returnValue = RefGA.Multivector.Add(m_returnValue, RefGA.Multivector.gp( RefGA.Multivector.gp(omColumnValue, inputBladeScalarMultiplier), domainBladeScalarMultiplier)); break; // no need to search the other domainBlades too } } } // 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(); } }