def set_diff_order(self, order): if order > 1: raise ValueError("Only supports 0 or 1 differential order") # self.monomial_basis.set_diff_order(order) #nonsense about mls self.weight_func.set_diff_order(order) self._diff_order = order self.mat_As = [] base_dim = self.basis.size() self._t_mat = np.ndarray((base_dim, base_dim), dtype=np.double) for _i in xrange(output_length_2d(order)): self.mat_As.append(np.ndarray((base_dim, base_dim), dtype=np.double))
def value(self, xy): res_length = output_length_2d(self._diff_order) res = np.ndarray((res_length,), dtype=np.double) dists, rads, indes = self._search_supporting(xy) vs = self.base.values(dists, rads) for i in xrange(res_length): t = 0 k = 0 for j in indes: t += vs[k, i] * self.a[j] k += 1 res[i] = t return res
def values(self, center, coords, influence_rads, dists=None): center = np.array(center, dtype=np.double) if None is dists: dists = _dists(center, coords, self.diff_order) weights = self.weight_func.values(dists, influence_rads) self._zero_mat_As() mat_As = self.mat_As t_mat = self._t_mat num_col = output_length_2d(self.diff_order) mat_Bs = self._gen_mat_Bs(len(coords)) self.basis.set_diff_order(0) for i in xrange(len(coords)): nd_crd = coords[i] p = self.basis.values(nd_crd - center) for diff_index in xrange(num_col): w = weights[i][diff_index] mat_B = mat_Bs[diff_index] mat_B[i] = p mat_B[i] *= w mat_A = mat_As[diff_index] np.multiply(p.reshape((-1, 1)), p, t_mat) t_mat *= w mat_A += t_mat self.basis.set_diff_order(self.diff_order) if self.diff_order > 0: self.basis.set_diff_order(self.diff_order) p = self.basis.values((0.0, 0.0)) g = np.linalg.solve(mat_As[0], p[0]) results = np.ndarray((len(coords), num_col), dtype=np.double) results[:, 0] = np.dot(mat_Bs[0], g) if self.diff_order > 0: g_x = np.linalg.solve(mat_As[0], p[1] - np.dot(mat_As[1], g)) g_y = np.linalg.solve(mat_As[0], p[2] - np.dot(mat_As[2], g)) results[:, 1] = np.dot(mat_Bs[1], g) + np.dot(mat_Bs[0], g_x) results[:, 2] = np.dot(mat_Bs[2], g) + np.dot(mat_Bs[0], g_y) return results
def _dists(center, coords, diff_order): num_col = output_length_2d(diff_order) result = np.ndarray((len(coords), num_col), dtype=np.double) for i in xrange(len(coords)): d_xy = center - coords[i] dst = np.dot(d_xy, d_xy) ** 0.5 result[i][0] = dst if diff_order == 1: if dst == 0: result[i, 1:] = 0 else: result[i][1] = d_xy[0] / dst result[i][2] = d_xy[1] / dst return result
def values(self, dists, infl_rads): num_col = output_length_2d(self.diff_order) results = np.ndarray((len(dists), num_col), dtype=np.double) if len(infl_rads) == 1: uni_rad = infl_rads[0] else: uni_rad = None i = 0 if not uni_rad: rad_iter = iter(infl_rads) for dist in dists: if uni_rad: rad = uni_rad else: rad = next(rad_iter) core_value = self.core_func(dist[0] / rad) results[i][0] = core_value[0] for j in xrange(1, num_col): results[i][j] = core_value[1] / rad * dist[j] i += 1 return results
def monomial_basis(xy, base_order, diff_order): if diff_order < 0 or diff_order > 1: raise ValueError("Only supports diff_order = 0 or 1") if base_order< 0: raise ValueError("monomial order should be non-negative") num_row = output_length_2d(diff_order) num_col = bases_length(base_order) res = np.ndarray((num_row, num_col), dtype=np.double) x, y = xy p = (1, x, y, x ** 2, x * y, y ** 2) if diff_order >= 1: p_x = (0, 1, 0, 2 * x, y, 0) p_y = (0, 0, 1, 0, x, 2 * y) if num_col <= len(p): res[0] = p[:num_col] if diff_order >= 1: res[1] = p_x[:num_col] res[2] = p_y[:num_col] else: res[0, :len(p)] = p if diff_order >= 1: res[1, :len(p)] = p_x res[2, :len(p)] = p_y for n in xrange(2, base_order): i1 = bases_length(n - 1) i2 = bases_length(n) for i in xrange(i2 - i1): res[0, i2 + i + 1] = y * res[0, i1 + i] if diff_order >= 1: res[1, i2 + i + 1] = y * res[1, i1 + i] res[2, i2 + i] = x * res[2, i1 + i] res[0, i2] = res[0, i1] * x if diff_order >= 1: res[1, i2] = res[0, i1] * (n + 1) res[2, i2 + n + 1] = res[0, i1 + n] * (n + 1) return res
def _gen_mat_Bs(self, coords_lens): mat_Bs = [] for _i in xrange(output_length_2d(self.diff_order)): mat_Bs.append(np.zeros((coords_lens, self.basis.size()))) return mat_Bs