private void init(WeightFunction weightFunction, BasesFunction baseFunction) { this.weightFunction = weightFunction; this.basesFunction = baseFunction; final int baseDim = baseFunction.getDim(); A = new DenseMatrix64F(baseDim, baseDim); A_x = new DenseMatrix64F(baseDim, baseDim); A_y = new DenseMatrix64F(baseDim, baseDim); As = new DenseMatrix64F[] {A, A_x, A_y}; B = new ArrayList<>(baseDim); B_x = new ArrayList<>(baseDim); B_y = new ArrayList<>(baseDim); Bs = Arrays.asList(B, B_x, B_y); for (ArrayList<TDoubleArrayList> tB : Bs) { for (int i = 0; i < baseDim; i++) { tB.add(new TDoubleArrayList(ShapeFunctionUtils2D.MAX_NODES_SIZE_GUESS)); } } gamma = new DenseMatrix64F(baseDim, 1); gamma_x = new DenseMatrix64F(baseDim, 1); gamma_y = new DenseMatrix64F(baseDim, 1); ps_arr = new double[3][baseDim]; p = DenseMatrix64F.wrap(ps_arr[0].length, 1, ps_arr[0]); p_x = DenseMatrix64F.wrap(ps_arr[1].length, 1, ps_arr[1]); p_y = DenseMatrix64F.wrap(ps_arr[2].length, 1, ps_arr[2]); tv = new DenseMatrix64F(baseDim, 1); luSolver = new LinearSolverLu(new LUDecompositionAlt()); A_bak = new DenseMatrix64F(baseDim, baseDim); }
@Override public TDoubleArrayList[] values( Coordinate pos, List<? extends Coordinate> nodes, TDoubleArrayList[] distSquares, TDoubleArrayList infRads, TDoubleArrayList[] results) { if (null == distSquares) { distSquares = this.distSquaresCache; euclideanDistSqFun.setPosition(pos); euclideanDistSqFun.sqValues(nodes, distSquares); } int ndsNum = nodes.size(); weightFunction.values(distSquares, infRads, nodesWeightsCache); results = ShapeFunctionUtils2D.init4Output(results, diffOrder, ndsNum); int diffDim = CommonUtils.len2DBase(diffOrder); int baseDim = basesFunction.getDim(); Coordinate zero = new Coordinate(0, 0, 0); Coordinate radCoord = new Coordinate(0, 0, 0); for (int i = 0; i < diffDim; i++) { As[i].zero(); ArrayList<TDoubleArrayList> tB = Bs.get(i); for (int j = 0; j < baseDim; j++) { TDoubleArrayList v = tB.get(j); v.resetQuick(); v.ensureCapacity(ndsNum); v.fill(0, ndsNum, 0); } } basesFunction.setDiffOrder(0); for (int diffDimIdx = 0; diffDimIdx < diffDim; diffDimIdx++) { TDoubleArrayList weights_d = nodesWeightsCache[diffDimIdx]; DenseMatrix64F A_d = As[diffDimIdx]; ArrayList<TDoubleArrayList> B_d = Bs.get(diffDimIdx); double[] tp = ps_arr[0]; int ndIdx = 0; for (Coordinate nd : nodes) { if (areBasesRelative) { GeometryMath.minus(nd, pos, radCoord); basesFunction.values(radCoord, ps_arr); } else { basesFunction.values(nd, ps_arr); } double weight_d = weights_d.getQuick(ndIdx); for (int i = 0; i < baseDim; i++) { double p_i = tp[i]; for (int j = 0; j < baseDim; j++) { double p_ij = p_i * tp[j]; A_d.add(i, j, weight_d * p_ij); } B_d.get(i).set(ndIdx, weight_d * p_i); } ndIdx++; } } basesFunction.setDiffOrder(diffOrder); if (areBasesRelative) { basesFunction.values(zero, ps_arr); } else { basesFunction.values(pos, ps_arr); } A_bak.set(A); luSolver.setA(A_bak); tv.set(p); luSolver.solve(tv, gamma); // CommonOps.solve(A, p, gamma); ShapeFunctionUtils2D.multAddTo(gamma, B, results[0]); if (diffOrder < 1) { return results; } tv.zero(); CommonOps.mult(-1, A_x, gamma, tv); CommonOps.add(p_x, tv, tv); luSolver.solve(tv, gamma_x); // CommonOps.solve(A, tv, gamma_x); tv.zero(); CommonOps.mult(-1, A_y, gamma, tv); CommonOps.add(p_y, tv, tv); luSolver.solve(tv, gamma_y); // CommonOps.solve(A, tv, gamma_y); ShapeFunctionUtils2D.multAddTo(gamma_x, B, results[1]); ShapeFunctionUtils2D.multAddTo(gamma, B_x, results[1]); ShapeFunctionUtils2D.multAddTo(gamma_y, B, results[2]); ShapeFunctionUtils2D.multAddTo(gamma, B_y, results[2]); return results; }