//Algorithm 2 //page: A1005 private void SurfaceIntegrand(MultidimensionalArray X, double X_weight, T arg, bool isNew) { Debug.Assert(arg.n == 1); //Calculate the roots of phi in the interval R = ... (line 1) S phi = arg.PsiAndS[0].Item1; int heightDirection = arg.HeightDirection; double[] bounds = GetBoundaries(arg, heightDirection); ISortedBoundedList <double> roots = new SayeSortedList(3, 1.0e-14); roots.SetBounds(bounds[0], bounds[1]); double[] newRoots = FindRoots(phi, X, heightDirection, bounds, this.cell); roots.Add(newRoots); //if there is a root, insert node Debug.Assert(roots.Count() <= 3); if (roots.Count() > 2) { X[0, heightDirection] = roots[1]; SayeQuadRule surfaceQuadNode = BuildSurfaceQuadRule(X, X_weight, heightDirection, this.cell); arg.NodesAndWeights.AddRule(surfaceQuadNode, true); } //else remove node else { arg.NodesAndWeights.RemoveActiveNode(); } }
//Algorithm 1 //page: A1005 private void VolumeIntegrand(MultidimensionalArray X, double X_weight, T arg, bool isNew) { //Calculate the set of roots and union with the interval endpoints ( line 1) int heightDirection = arg.HeightDirection; //Sort R into ascending order such that ... (line 2) : Implemented with a sortedList ISortedBoundedList <double> roots = new SayeSortedList(2 + arg.n, 1.0e-14); double[] bounds = GetBoundaries(arg, heightDirection); roots.SetBounds(bounds[0], bounds[1]); RestrictToBound(X, bounds[0], arg.HeightDirection); for (int i = 0; i < arg.n; ++i) { S psi_i = arg.PsiAndS[i].Item1; double[] rootsInPsi = FindRoots(psi_i, X, heightDirection, bounds, this.cell); roots.Add(rootsInPsi); } //For j = 1 to l - 1 do (line 4) bool xIsUnchanged = true; for (int j = 0; j < roots.Count() - 1; ++j) { //Define L and x_c(line 5) double L = roots[j + 1] - roots[j]; NodeSet x_c = NodeOnRay(X, heightDirection, roots[j] - roots[0] + L / 2.0); //If s_i * psi_i >= 0 for all i (line 6) bool updateIntegrand = true; foreach (Tuple <S, int> psiAndS in arg.PsiAndS) { S psi_i = psiAndS.Item1; int s_i = psiAndS.Item2; updateIntegrand &= s_i * EvaluateAt(psi_i, x_c) >= 0; } //Update I = ...(line 7) if (updateIntegrand) { SayeQuadRule newRule = BuildQuadRule(x_c, X_weight, heightDirection, L); bool deriveFromExistingNode = !isNew && xIsUnchanged; arg.NodesAndWeights.AddRule(newRule, deriveFromExistingNode); xIsUnchanged = false; } } if (xIsUnchanged && !isNew) { arg.NodesAndWeights.RemoveActiveNode(); } }