def projected(self, source_basis, range_basis, product=None, name=None): assert source_basis is None or source_basis in self.source assert range_basis is None or range_basis in self.range assert product is None or product.source == product.range == self.range if len(self.interpolation_dofs) == 0: return ZeroOperator(self.source, self.range, self.name).projected(source_basis, range_basis, product, name) elif not hasattr(self, 'restricted_operator') or source_basis is None: return super(EmpiricalInterpolatedOperator, self).projected(source_basis, range_basis, product, name) else: name = name or self.name + '_projected' if range_basis is not None: if product is None: projected_collateral_basis = NumpyVectorArray(self.collateral_basis.dot(range_basis, pairwise=False)) else: projected_collateral_basis = NumpyVectorArray(product.apply2(self.collateral_basis, range_basis, pairwise=False)) else: projected_collateral_basis = self.collateral_basis return ProjectedEmpiciralInterpolatedOperator(self.restricted_operator, self.interpolation_matrix, NumpyVectorArray(source_basis.components(self.source_dofs), copy=False), projected_collateral_basis, self.triangular, name)
def jacobian(self, U, mu=None): mu = self.parse_parameter(mu) if len(self.interpolation_dofs) == 0: if self.source.type == self.range.type == NumpyVectorArray: return NumpyMatrixOperator(np.zeros((0, self.source.dim)), name=self.name + '_jacobian') else: return ZeroOperator(self.source, self.range, name=self.name + '_jacobian') elif hasattr(self, 'operator'): return EmpiricalInterpolatedOperator(self.operator.jacobian(U, mu=mu), self.interpolation_dofs, self.collateral_basis, self.triangular, self.name + '_jacobian') else: U_components = NumpyVectorArray(U.components(self.source_dofs), copy=False) JU = self.restricted_operator.jacobian(U_components, mu=mu) \ .apply(NumpyVectorArray(np.eye(len(self.source_dofs)), copy=False)) try: if self.triangular: interpolation_coefficients = solve_triangular(self.interpolation_matrix, JU.data.T, lower=True, unit_diagonal=True).T else: interpolation_coefficients = np.linalg.solve(self.interpolation_matrix, JU._array.T).T except ValueError: # this exception occurs when AU contains NaNs ... interpolation_coefficients = np.empty((len(JU), len(self.collateral_basis))) + np.nan J = self.collateral_basis.lincomb(interpolation_coefficients) if isinstance(J, NumpyVectorArray): J = NumpyMatrixOperator(J.data.T) else: J = VectorArrayOperator(J, copy=False) return Concatenation(J, ComponentProjection(self.source_dofs, self.source), name=self.name + '_jacobian')
def projected_to_subbasis(self, dim_source=None, dim_range=None, dim_collateral=None, name=None): assert dim_source is None or dim_source <= self.source.dim assert dim_range is None or dim_range <= self.range.dim assert dim_collateral is None or dim_collateral <= self.restricted_operator.range.dim if not isinstance(self.projected_collateral_basis, NumpyVectorArray): raise NotImplementedError name = name or '{}_projected_to_subbasis'.format(self.name) interpolation_matrix = self.interpolation_matrix[:dim_collateral, :dim_collateral] if dim_collateral is not None: restricted_operator, source_dofs = self.restricted_operator.restricted(np.arange(dim_collateral)) else: restricted_operator = self.restricted_operator old_pcb = self.projected_collateral_basis projected_collateral_basis = NumpyVectorArray(old_pcb.data[:dim_collateral, :dim_range], copy=False) old_sbd = self.source_basis_dofs source_basis_dofs = NumpyVectorArray(old_sbd.data[:dim_source], copy=False) if dim_collateral is None \ else NumpyVectorArray(old_sbd.data[:dim_source, source_dofs], copy=False) return ProjectedEmpiciralInterpolatedOperator(restricted_operator, interpolation_matrix, source_basis_dofs, projected_collateral_basis, self.triangular, name=name)
def projected(self, source_basis, range_basis, product=None, name=None): assert source_basis is None or source_basis in self.source assert range_basis is None or range_basis in self.range assert product is None or product.source == product.range == self.range if range_basis is not None: if product: projected_value = NumpyVectorArray(product.apply2( range_basis, self._value, pairwise=False).T, copy=False) else: projected_value = NumpyVectorArray(range_basis.dot( self._value, pairwise=False).T, copy=False) else: projected_value = self._value if source_basis is None: return ConstantOperator(projected_value, self.source, copy=False, name=self.name + '_projected') else: return ConstantOperator(projected_value, NumpyVectorSpace(len(source_basis)), copy=False, name=self.name + '_projected')
def apply_adjoint(self, U, ind=None, mu=None, source_product=None, range_product=None): assert U in self.range assert source_product is None or source_product.source == source_product.range == self.source assert range_product is None or range_product.source == range_product.range == self.range if not self.transposed: if range_product: ATPrU = NumpyVectorArray(range_product.apply2( self._array, U, U_ind=ind, pairwise=False).T, copy=False) else: ATPrU = NumpyVectorArray(self._array.dot(U, o_ind=ind, pairwise=False).T, copy=False) if source_product: return source_product.apply_inverse(ATPrU) else: return ATPrU else: if range_product: PrU = range_product.apply(U, ind=ind) else: PrU = U.copy(ind) ATPrU = self._array.lincomb(PrU.data) if source_product: return source_product.apply_inverse(ATPrU) else: return ATPrU
def apply(self, U, ind=None, mu=None): mu = self.parse_parameter(mu) if self.source_basis is None: if self.range_basis is None: return self.operator.apply(U, ind=ind, mu=mu) elif self.product is None: return NumpyVectorArray( self.operator.apply2(self.range_basis, U, U_ind=ind, mu=mu, pairwise=False).T) else: V = self.operator.apply(U, ind=ind, mu=mu) return NumpyVectorArray( self.product.apply2(V, self.range_basis, pairwise=False)) else: U_array = U._array[:U._len] if ind is None else U._array[ind] UU = self.source_basis.lincomb(U_array) if self.range_basis is None: return self.operator.apply(UU, mu=mu) elif self.product is None: return NumpyVectorArray( self.operator.apply2(self.range_basis, UU, mu=mu, pairwise=False).T) else: V = self.operator.apply(UU, mu=mu) return NumpyVectorArray( self.product.apply2(V, self.range_basis, pairwise=False))
def initial_projection(U, mu): I = p.initial_data.evaluate(grid.quadrature_points(0, order=2), mu).squeeze() I = np.sum(I * grid.reference_element.quadrature(order=2)[1], axis=1) * (1. / grid.reference_element.volume) I = NumpyVectorArray(I, copy=False) return I.lincomb(U).data
def test_gram_schmidt(): for i in (1, 32): b = NumpyVectorArray(np.identity(i, dtype=np.float)) a = gram_schmidt(b) assert b == a c = NumpyVectorArray([[1.0, 0], [0., 0]]) a = gram_schmidt(c) assert (a.data == np.array([[1.0, 0]])).all()
def numpy_matrix_operator_with_arrays_factory(dim_source, dim_range, count_source, count_range, seed): np.random.seed(seed) op = NumpyMatrixOperator(np.random.random((dim_range, dim_source))) s = NumpyVectorArray(np.random.random((count_source, dim_source)), copy=False) r = NumpyVectorArray(np.random.random((count_range, dim_range)), copy=False) return op, None, s, r
def apply(self, U, ind=None, mu=None): assert U in self.source assert U.check_ind(ind) U_array = U._array[:U._len] if ind is None else U._array[ind] if self.parametric: mu = self.parse_parameter(mu) return NumpyVectorArray(self._mapping(U_array, mu=mu), copy=False) else: return NumpyVectorArray(self._mapping(U_array), copy=False)
def test_ext(extension_alg): size = 5 ident = np.identity(size) current = ident[0] for i in range(1, size): c = NumpyVectorArray(current) n, _ = extension_alg(c, NumpyVectorArray(ident[i])) assert np.allclose(n.data, ident[0:i + 1]) current = ident[0:i + 1]
def test_projected(operator_with_arrays): op, mu, U, V = operator_with_arrays op_UV = op.projected(U, V) np.random.seed(4711 + U.dim + len(V)) coeffs = np.random.random(len(U)) X = op_UV.apply(NumpyVectorArray(coeffs, copy=False), mu=mu) Y = NumpyVectorArray(V.dot(op.apply(U.lincomb(coeffs), mu=mu), pairwise=False).T, copy=False) assert np.all(X.almost_equal(Y))
def test_projected_with_product(operator_with_arrays_and_products): op, mu, U, V, sp, rp = operator_with_arrays_and_products op_UV = op.projected(U, V, product=rp) np.random.seed(4711 + U.dim + len(V)) coeffs = np.random.random(len(U)) X = op_UV.apply(NumpyVectorArray(coeffs, copy=False), mu=mu) Y = NumpyVectorArray(rp.apply2(op.apply(U.lincomb(coeffs), mu=mu), V, pairwise=False), copy=False) assert np.all(X.almost_equal(Y))
def thermalblock_vectorarray_factory(transposed, xblocks, yblocks, diameter, seed): from pymor.operators.constructions import VectorArrayOperator _, _, U, V, sp, rp = thermalblock_factory(xblocks, yblocks, diameter, seed) op = VectorArrayOperator(U, transposed) if transposed: U = V V = NumpyVectorArray(np.random.random((7, op.range.dim)), copy=False) sp = rp rp = NumpyMatrixOperator(np.eye(op.range.dim) * 2) else: U = NumpyVectorArray(np.random.random((7, op.source.dim)), copy=False) sp = NumpyMatrixOperator(np.eye(op.source.dim) * 2) return op, None, U, V, sp, rp
def apply(self, U, ind=None, mu=None): U_id = self.rv.apply(self._apply, self.rid, U.rid, ind=ind, mu=mu) if self.dim_range > 1: return self.type_range(U_id) else: return NumpyVectorArray( self.real_type_range(U_id).components([0]))
def visualize(self, U, codim=2, **kwargs): """Visualize scalar data associated to the grid as a patch plot. Parameters ---------- U |VectorArray| of the data to visualize. If `len(U) > 1`, the data is visualized as a time series of plots. Alternatively, a tuple of |VectorArrays| can be provided, in which case a subplot is created for each entry of the tuple. The lengths of all arrays have to agree. codim The codimension of the entities the data in `U` is attached to (either 0 or 2). kwargs See :func:`~pymor.gui.qt.visualize_patch` """ from pymor.gui.qt import visualize_patch from pymor.la.numpyvectorarray import NumpyVectorArray if not isinstance(U, NumpyVectorArray): U = NumpyVectorArray(U, copy=False) bounding_box = kwargs.pop('bounding_box', self.domain) visualize_patch(self, U, codim=codim, bounding_box=bounding_box, **kwargs)
def thermalblock_vector_factory(xblocks, yblocks, diameter, seed): from pymor.operators.constructions import VectorOperator _, _, U, V, sp, rp = thermalblock_factory(xblocks, yblocks, diameter, seed) op = VectorOperator(U.copy(ind=0)) U = NumpyVectorArray(np.random.random((7, 1)), copy=False) sp = NumpyMatrixOperator(np.eye(1) * 2) return op, None, U, V, sp, rp
def test_induced(): grid = TriaGrid(num_intervals=(10, 10)) boundary_info = AllDirichletBoundaryInfo(grid) product = L2ProductP1(grid, boundary_info) zero = NumpyVectorArray(np.zeros(grid.size(2))) norm = induced_norm(product) value = norm(zero) np.testing.assert_almost_equal(value, 0.0)
def thermalblock_vectorfunc_factory(product, xblocks, yblocks, diameter, seed): from pymor.operators.constructions import VectorFunctional _, _, U, V, sp, rp = thermalblock_factory(xblocks, yblocks, diameter, seed) op = VectorFunctional(U.copy(ind=0), product=sp if product else None) U = V V = NumpyVectorArray(np.random.random((7, 1)), copy=False) sp = rp rp = NumpyMatrixOperator(np.eye(1) * 2) return op, None, U, V, sp, rp
def apply_inverse(self, U, ind=None, mu=None, options=None): assert U in self.range assert U.check_ind(ind) if U.dim == 0: if (self.source.dim == 0 or isinstance(options, str) and options.startswith('least_squares') or isinstance(options, dict) and options['type'].startswith('least_squares')): return NumpyVectorArray( np.zeros((U.len_ind(ind), self.source.dim))) else: raise InversionError U = U.data if ind is None else \ U.data[ind] if hasattr(ind, '__len__') else U.data[ind:ind + 1] return NumpyVectorArray(numpysolvers.apply_inverse(self._matrix, U, options=options), copy=False)
def apply(self, U, ind=None, mu=None): assert U in self.source if not self.transposed: if ind is not None: U = U.copy(ind) return self._array.lincomb(U.data) else: return NumpyVectorArray(U.dot(self._array, ind=ind, pairwise=False), copy=False)
def reconstruct(self, U): """Reconstruct high-dimensional vector from reduced vector `U`.""" assert isinstance(U, NumpyVectorArray) UU = np.zeros((len(U), self.dim)) UU[:, :self.dim_subbasis] = U.data UU = NumpyVectorArray(UU, copy=False) if self.old_recontructor: return self.old_recontructor.reconstruct(UU) else: return UU
def apply(self, U, ind=None, mu=None): mu = self.parse_parameter(mu) if len(self.interpolation_dofs) == 0: count = len(ind) if ind is not None else len(U) return self.range.zeros(count=count) if hasattr(self, 'restricted_operator'): U_components = NumpyVectorArray(U.components(self.source_dofs, ind=ind), copy=False) AU = self.restricted_operator.apply(U_components, mu=mu) else: AU = NumpyVectorArray(self.operator.apply(U, mu=mu).components(self.interpolation_dofs), copy=False) try: if self.triangular: interpolation_coefficients = solve_triangular(self.interpolation_matrix, AU.data.T, lower=True, unit_diagonal=True).T else: interpolation_coefficients = np.linalg.solve(self.interpolation_matrix, AU._array.T).T except ValueError: # this exception occurs when AU contains NaNs ... interpolation_coefficients = np.empty((len(AU), len(self.collateral_basis))) + np.nan return self.collateral_basis.lincomb(interpolation_coefficients)
def save(self): if not HAVE_PYVTK: msg = QMessageBox(QMessageBox.Critical, 'Error', 'VTK output disabled. Pleas install pyvtk.') msg.exec_() return filename = QFileDialog.getSaveFileName(self, 'Save as vtk file')[0] base_name = filename.split('.vtu')[0].split('.vtk')[0].split( '.pvd')[0] if base_name: if len(self.U) == 1: write_vtk(self.grid, NumpyVectorArray(self.U[0], copy=False), base_name, codim=self.codim) else: for i, u in enumerate(self.U): write_vtk(self.grid, NumpyVectorArray(u, copy=False), '{}-{}'.format(base_name, i), codim=self.codim)
def apply(self, U, ind=None, mu=None): assert isinstance(U, NumpyVectorArray) assert U in self.source mu = self.parse_parameter(mu) ind = xrange(len(U)) if ind is None else ind U = U.data R = np.zeros((len(ind), self.source.dim)) g = self.grid bi = self.boundary_info SUPE = g.superentities(1, 0) SUPI = g.superentity_indices(1, 0) assert SUPE.ndim == 2 VOLS = g.volumes(1) boundaries = g.boundaries(1) unit_outer_normals = g.unit_outer_normals()[SUPE[:, 0], SUPI[:, 0]] if bi.has_dirichlet: dirichlet_boundaries = bi.dirichlet_boundaries(1) if hasattr(self, '_dirichlet_values'): dirichlet_values = self._dirichlet_values elif self.dirichlet_data is not None: dirichlet_values = self.dirichlet_data(g.centers(1)[dirichlet_boundaries], mu=mu) else: dirichlet_values = np.zeros_like(dirichlet_boundaries) F_dirichlet = self.numerical_flux.evaluate_stage1(dirichlet_values, mu) for i, j in enumerate(ind): Ui = U[j] Ri = R[i] F = self.numerical_flux.evaluate_stage1(Ui, mu) F_edge = [f[SUPE] for f in F] for f in F_edge: f[boundaries, 1] = f[boundaries, 0] if bi.has_dirichlet: for f, f_d in izip(F_edge, F_dirichlet): f[dirichlet_boundaries, 1] = f_d NUM_FLUX = self.numerical_flux.evaluate_stage2(F_edge, unit_outer_normals, VOLS, mu) if bi.has_neumann: NUM_FLUX[bi.neumann_boundaries(1)] = 0 iadd_masked(Ri, NUM_FLUX, SUPE[:, 0]) isub_masked(Ri, NUM_FLUX, SUPE[:, 1]) R /= g.volumes(0) return NumpyVectorArray(R)
def test_lincomb_op(): p1 = MonomOperator(1) p2 = MonomOperator(2) p12 = p1 + p2 p0 = p1 - p1 x = np.linspace(-1., 1., num=3) vx = NumpyVectorArray(x[:, np.newaxis]) assert np.allclose(p0.apply(vx).data, [0.]) assert np.allclose(p12.apply(vx).data, (x * x + x)[:, np.newaxis]) assert np.allclose((p1 * 2.).apply(vx).data, (x * 2.)[:, np.newaxis]) assert p2.jacobian(vx).apply(vx).almost_equal(p1.apply(vx) * 2.).all() assert p0.jacobian(vx).apply(vx).almost_equal(vx * 0.).all() with pytest.raises(TypeError): p2.as_vector() p1.as_vector() assert p1.as_vector().almost_equal(p1.apply(NumpyVectorArray(1.))) basis = NumpyVectorArray([1.]) for p in (p1, p2, p12): projected = p.projected(basis, basis) pa = projected.apply(vx) assert pa.almost_equal(p.apply(vx)).all()
def as_vector(self, mu=None): if not self.linear: raise TypeError( 'This nonlinear operator does not represent a vector or linear functional.' ) elif self.source.dim == 1 and self.source.type is NumpyVectorArray: return self.apply(NumpyVectorArray(1), mu=mu) elif self.range.dim == 1 and self.range.type is NumpyVectorArray: raise NotImplementedError else: raise TypeError( 'This operator does not represent a vector or linear functional.' )
def test_vtkio(rect_or_tria_grid): grid = rect_or_tria_grid steps = 4 for dim in range(1, 2): for codim, data in enumerate( (NumpyVectorArray(np.zeros((steps, grid.size(c)))) for c in range(grid.dim + 1))): with NamedTemporaryFile('wb') as out: if codim == 1: with pytest.raises(NotImplementedError): write_vtk(grid, data, out.name, codim=codim) else: write_vtk(grid, data, out.name, codim=codim)
def test_projected_with_product_2(operator_with_arrays_and_products): op, mu, U, V, sp, rp = operator_with_arrays_and_products op_U = op.projected(U, None) op_V = op.projected(None, V, product=rp) op_U_V = op_U.projected(None, V, product=rp) op_V_U = op_V.projected(U, None) op_UV = op.projected(U, V, product=rp) np.random.seed(4711 + U.dim + len(V)) W = NumpyVectorArray(np.random.random(len(U)), copy=False) Y0 = op_UV.apply(W, mu=mu) Y1 = op_U_V.apply(W, mu=mu) Y2 = op_V_U.apply(W, mu=mu) assert np.all(Y0.almost_equal(Y1)) assert np.all(Y0.almost_equal(Y2))
def apply_adjoint(self, U, ind=None, mu=None, source_product=None, range_product=None): assert U in self.range assert U.check_ind(ind) assert source_product is None or source_product.source == source_product.range == self.source assert range_product is None or range_product.source == range_product.range == self.range if range_product: PrU = range_product.apply(U, ind=ind).data else: PrU = U.data if ind is None else U.data[ind] ATPrU = NumpyVectorArray(self._matrix.T.dot(PrU.T).T, copy=False) if source_product: return source_product.apply_inverse(ATPrU) else: return ATPrU