/// <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) { 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) { m_fgs.m_returnTypeName = m_gmv.Name; // gmv * gmv = gmv } else { // compute return value if (IsInverse(m_fgs)) { m_returnValue = RefGA.Multivector.ihp(tmpFAI[0].MultivectorValue[0], tmpFAI[1].MultivectorValue[0]); } else { m_returnValue = RefGA.Multivector.hp(tmpFAI[0].MultivectorValue[0], tmpFAI[1].MultivectorValue[0]); } bool getReturnType = (m_fgs.m_returnTypeName.Length == 0); // get name of return type if (getReturnType) { m_fgs.m_returnTypeName = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue).GetName(); } // This code corrects the result for the signs of the basis blade, and loops until the return type converges. // The reason for this code is that the hadamard product is not well-defined when the basis blades of the operands and the result do not match. while (true) { G25.VariableType returnType = m_specification.GetType(m_fgs.m_returnTypeName); if (returnType is G25.SMV) { G25.SMV returnSMV = returnType as G25.SMV; RefGA.Multivector unitReturnSmv = returnSMV.ToMultivectorValue(); RefGA.Multivector correctedReturnValue = RefGA.Multivector.ihp(m_returnValue, unitReturnSmv); if (getReturnType) { string newReturnTypeName = G25.CG.Shared.SpecializedReturnType.GetReturnType(m_specification, m_cgd, m_fgs, FT, m_returnValue).GetName(); if (newReturnTypeName == m_fgs.m_returnTypeName) { m_returnValue = correctedReturnValue; break; } else { m_fgs.m_returnTypeName = newReturnTypeName; } } else { m_returnValue = correctedReturnValue; break; } } else { break; } } } }