protected override bool HeightDirectionIsSuitable( LinearSayeSpace <Cube> arg, LinearPSI <Cube> psi, NodeSet x_center, int heightDirection, MultidimensionalArray agradient, int cell) { //throw new NotImplementedException(); //Determine bounds //----------------------------------------------------------------------------------------------------------------- NodeSet nodeOnPsi = psi.ProjectOnto(x_center); MultidimensionalArray jacobian = grid.Jacobian.GetValue_Cell(nodeOnPsi, cell, 1); jacobian = jacobian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 }); LevelSet levelSet = lsData.LevelSet as LevelSet; MultidimensionalArray hessian = MultidimensionalArray.Create(1, 1, 3, 3); levelSet.EvaluateHessian(cell, 1, nodeOnPsi, hessian); hessian = hessian.ExtractSubArrayShallow(new int[] { 0, 0, -1, -1 }).CloneAs(); //hessian = jacobian * hessian; hessian.ApplyAll(x => Math.Abs(x)); MultidimensionalArray gradient = lsData.GetLevelSetGradients(nodeOnPsi, cell, 1); gradient = gradient.ExtractSubArrayShallow(0, 0, -1).CloneAs(); //abs(Hessian) * 0,5 * diameters.^2 = delta ,( square each entry of diameters) , //this bounds the second error term from taylor series //+ + + + double[] arr = arg.Diameters.CloneAs(); psi.SetInactiveDimsToZero(arr); MultidimensionalArray diameters = MultidimensionalArray.CreateWrapper(arr, 3, 1); diameters = jacobian * diameters; diameters.ApplyAll(x => 0.5 * x * x); MultidimensionalArray delta = hessian * diameters; delta = delta.ExtractSubArrayShallow(-1, 0); //Check if suitable //----------------------------------------------------------------------------------------------------------------- //|gk| > δk //Gradient should be able to turn arround psi.SetInactiveDimsToZero(gradient.Storage); if (Math.Abs(gradient[heightDirection]) > delta[heightDirection]) { bool suitable = true; // ||Grad + maxChange|| should be smaller than 20 * // Sum_j( g_j + delta_j)^2 / (g_k - delta_k)^2 < 20 double sum = 0; for (int j = 0; j < delta.Length; ++j) { sum += Math.Pow(Math.Abs(gradient[j]) + delta[j], 2); } sum /= Math.Pow(Math.Abs(gradient[heightDirection]) - delta[heightDirection], 2); suitable &= sum < 20; return(suitable); } return(false); }