Exemplo n.º 1
0
def test_selection_op():
    p1 = MonomOperator(1)
    select_rhs_functional = GenericParameterFunctional(
        lambda x: round(float(x["nrrhs"])), ParameterType({"nrrhs": ()}))
    s1 = SelectionOperator(operators=[p1],
                           boundaries=[],
                           parameter_functional=select_rhs_functional,
                           name="foo")
    x = np.linspace(-1., 1., num=3)
    vx = p1.source.make_array(x[:, np.newaxis])
    assert np.allclose(
        p1.apply(vx, mu=0).to_numpy(),
        s1.apply(vx, mu=0).to_numpy())

    s2 = SelectionOperator(operators=[p1, p1, p1, p1],
                           boundaries=[-3, 3, 7],
                           parameter_functional=select_rhs_functional,
                           name="Bar")

    assert s2._get_operator_number({"nrrhs": -4}) == 0
    assert s2._get_operator_number({"nrrhs": -3}) == 0
    assert s2._get_operator_number({"nrrhs": -2}) == 1
    assert s2._get_operator_number({"nrrhs": 3}) == 1
    assert s2._get_operator_number({"nrrhs": 4}) == 2
    assert s2._get_operator_number({"nrrhs": 7}) == 2
    assert s2._get_operator_number({"nrrhs": 9}) == 3
Exemplo n.º 2
0
def elliptic_oned_demo(args):
    args['PROBLEM-NUMBER'] = int(args['PROBLEM-NUMBER'])
    assert 0 <= args['PROBLEM-NUMBER'] <= 1, ValueError('Invalid problem number.')
    args['N'] = int(args['N'])

    rhss = [GenericFunction(lambda X: np.ones(X.shape[:-1]) * 10, dim_domain=1),
            GenericFunction(lambda X: (X[..., 0] - 0.5) ** 2 * 1000, dim_domain=1)]
    rhs = rhss[args['PROBLEM-NUMBER']]

    d0 = GenericFunction(lambda X: 1 - X[..., 0], dim_domain=1)
    d1 = GenericFunction(lambda X: X[..., 0], dim_domain=1)

    parameter_space = CubicParameterSpace({'diffusionl': 0}, 0.1, 1)
    f0 = ProjectionParameterFunctional('diffusionl', 0)
    f1 = GenericParameterFunctional(lambda mu: 1, {})

    print('Solving on OnedGrid(({0},{0}))'.format(args['N']))

    print('Setup Problem ...')
    problem = EllipticProblem(domain=LineDomain(), rhs=rhs, diffusion_functions=(d0, d1),
                              diffusion_functionals=(f0, f1), dirichlet_data=ConstantFunction(value=0, dim_domain=1),
                              name='1DProblem')

    print('Discretize ...')
    discretizer = discretize_elliptic_fv if args['--fv'] else discretize_elliptic_cg
    discretization, _ = discretizer(problem, diameter=1 / args['N'])

    print('The parameter type is {}'.format(discretization.parameter_type))

    U = discretization.solution_space.empty()
    for mu in parameter_space.sample_uniformly(10):
        U.append(discretization.solve(mu))

    print('Plot ...')
    discretization.visualize(U, title='Solution for diffusionl in [0.1, 1]')
def build_output_coefficient(parameter_type,
                             parameter_weights=None,
                             mu_d_=None,
                             parameter_scales=None,
                             state_functional=None,
                             constant_part=None):
    def _collect_indices(item):
        item_dict = {}
        if sum(item) < 2:  # case () and (1,)
            item_dict[1] = ()
            new_item = ()
        else:
            assert len(item) == 1  # case (l,) with l > 1
            for l in range(item[0]):
                item_dict[l] = (l, )
            new_item = item
        return item_dict, new_item

    if parameter_weights is None:
        parameter_weights = {
            'walls': 1,
            'heaters': 1,
            'doors': 1,
            'windows': 1
        }
    if parameter_scales is None:
        parameter_scales = {'walls': 1, 'heaters': 1, 'doors': 1, 'windows': 1}
    mu_d = {}
    if mu_d_ is None:
        mu_d_ = {}
    for key, item in parameter_type.items():
        if not isinstance(parameter_weights[key], list):
            if len(item) == 0:  # for the case when item = ()
                parameter_weights[key] = [parameter_weights[key]]
            else:
                parameter_weights[key] = [
                    parameter_weights[key] for i in range(item[0])
                ]
        if key not in mu_d_:
            mu_d_[key] = 0
        if not isinstance(mu_d_[key], list):
            if len(item) == 0:  # for the case when item = ()
                mu_d[key] = [mu_d_[key]]
            else:
                if isinstance(mu_d_[key], type(np.array([]))):
                    mu_d[key] = [mu_d_[key][i] for i in range(item[0])]
                else:
                    mu_d[key] = [mu_d_[key] for i in range(item[0])]
        else:
            mu_d[key] = mu_d_[key]

    parameter_functionals = []

    if constant_part is not None:
        # sigma_d * constant_part
        parameter_functionals.append(state_functional * constant_part)
        # + 1
        parameter_functionals.append(ConstantParameterFunctional(1))

    def make_zero_expressions(parameter_type):
        zero_derivative_expression = {}
        for key, item in parameter_type.items():
            zero_expressions = np.array([], dtype='<U60')
            item_dict, new_item = _collect_indices(item)
            for (l, index) in item_dict.items():
                zero_expressions = np.append(zero_expressions, ['0'])
            if len(zero_expressions) == 1:
                zero_expressions = np.array(zero_expressions[0], dtype='<U60')
            else:
                zero_expressions = np.array(zero_expressions, dtype='<U60')
            zero_derivative_expression[key] = zero_expressions
        return zero_derivative_expression

    #prepare dict
    def make_dict_zero_expressions(parameter_type):
        zero_dict = {}
        for key, item in parameter_type.items():
            index_dict, new_item = _collect_indices(item)
            zero_ = np.empty(new_item, dtype=dict)
            zero_dict[key] = zero_
            for (l, index) in index_dict.items():
                zero_dict[key][index] = make_zero_expressions(parameter_type)
        return zero_dict

    for key, item in parameter_type.items():
        if len(item) == 0:  # for the case when item = ()
            weight = parameter_weights[key][0]
            derivative_expression = make_zero_expressions(parameter_type)
            derivative_expression[key] = '{}*{}**2*'.format(weight,parameter_scales[key]) \
                                          +'({}[{}]'.format(key,()) \
                                          +'-{}'.format(mu_d[key][0]) +')'
            second_derivative_expressions = make_dict_zero_expressions(
                parameter_type)
            second_derivative_expressions[key][()][key] = '{}*{}**2'.format(
                weight, parameter_scales[key])
            parameter_functionals.append(ExpressionParameterFunctional('{}*{}**2*0.5*({}[{}]'.format(
                                                                        weight,parameter_scales[key],key,()) \
                                                                        +'-{}'.format(mu_d[key][0])+')**2',
                                                                        parameter_type,
                                                                        derivative_expressions=derivative_expression,
                                                                        second_derivative_expressions=second_derivative_expressions))
        else:
            for i in range(item[0]):
                weight = parameter_weights[key][i]
                derivative_expression = make_zero_expressions(parameter_type)
                second_derivative_expressions = make_dict_zero_expressions(
                    parameter_type)
                if item[0] == 1:
                    derivative_expression[key] = \
                        '{}*{}**2*({}[{}]-'.format(weight,parameter_scales[key],key,i) + '{}'.format(mu_d[key][i])+')'
                    second_derivative_expressions[key][(
                    )][key] = '{}*{}**2'.format(weight, parameter_scales[key])
                else:
                    derivative_expression[key][i] = \
                            '{}*{}**2*({}[{}]-'.format(weight,parameter_scales[key],key,i) + '{}'.format(mu_d[key][i])+')'
                    second_derivative_expressions[key][i][key][
                        i] = '{}*{}**2'.format(weight, parameter_scales[key])
                parameter_functionals.append(ExpressionParameterFunctional('{}*{}**2*0.5*({}[{}]'.format( \
                                                                            weight,parameter_scales[key],key,i) \
                                                                            +'-{}'.format(mu_d[key][i])+')**2',
                                                                            parameter_type,
                                                                            derivative_expressions=derivative_expression,
                                                                            second_derivative_expressions=second_derivative_expressions))

    def mapping(mu):
        ret = 0
        for f in parameter_functionals:
            ret += f.evaluate(mu)
        return ret

    def make_mapping(key, i):
        def sum_derivatives(mu):
            ret = 0
            if i == -1:
                index = ()
            else:
                index = (i, )
            for f in parameter_functionals:
                ret += f.d_mu(key, index).evaluate(mu)
            return ret

        return sum_derivatives

    def make_second_mapping(key, i):
        def sum_second_derivatives(mu):
            ret = 0
            if i == -1:
                index = ()
            else:
                index = (i, )
            for f in parameter_functionals:
                ret += f.d_mu(key, index).d_mu(key, index).evaluate(mu)
            return ret

        return sum_second_derivatives

    def make_zero_mappings(parameter_type):
        zero_derivative_mappings = {}
        for key, item in parameter_type.items():
            zero_mappings = np.array([], dtype=object)
            zero_mapping = lambda mu: 0.
            if len(item) == 0:  # for the case when item = ()
                zero_mappings = np.append(zero_mappings, [zero_mapping])
                zero_mappings = np.array(zero_mappings[0])
            else:
                for i in range(item[0]):
                    zero_mappings = np.append(zero_mappings, [zero_mapping])
                if item[0] == 1:
                    zero_mappings = np.array(zero_mappings[0])
            zero_derivative_mappings[key] = zero_mappings
        return zero_derivative_mappings

    #prepare dict
    def make_dict_zero_mapping(parameter_type):
        zero_dict = {}
        for key, item in parameter_type.items():
            index_dict, new_item = _collect_indices(item)
            zero_ = np.empty(new_item, dtype=dict)
            zero_dict[key] = zero_
            for (l, index) in index_dict.items():
                zero_dict[key][index] = make_zero_mappings(parameter_type)
        return zero_dict

    derivative_mappings = make_zero_mappings(parameter_type)
    for key, item in parameter_type.items():
        if len(item) == 0:  # for the case when item = ()
            derivative_mappings[key] = np.array(make_mapping(key, -1))
        else:
            for i in range(item[0]):
                if item[0] == 1:
                    derivative_mappings[key] = np.array(make_mapping(key, -1))
                else:
                    derivative_mappings[key][i] = make_mapping(key, i)

    second_derivative_mappings = make_dict_zero_mapping(parameter_type)
    for key, item in parameter_type.items():
        if len(item) == 0:  # for the case when item = ()
            second_derivative_mappings[key][()][key] = np.array(
                make_second_mapping(key, -1))
        else:
            for i in range(item[0]):
                if item[0] == 1:
                    second_derivative_mappings[key][()][key] = np.array(
                        make_second_mapping(key, -1))
                else:
                    second_derivative_mappings[key][i][key][
                        i] = make_second_mapping(key, i)

    output_coefficient = GenericParameterFunctional(
        mapping,
        parameter_type,
        derivative_mappings=derivative_mappings,
        second_derivative_mappings=second_derivative_mappings)
    return output_coefficient
Exemplo n.º 4
0
def build_output_coefficient(parameters, parameter_weights=None, mu_d_=None, parameter_scales=None,
                             state_functional=None, constant_part=None):
    if parameter_weights is None:
        parameter_weights= {'walls': 1, 'heaters': 1, 'doors': 1, 'windows': 1}
    if parameter_scales is None:
        parameter_scales= {'walls': 1, 'heaters': 1, 'doors': 1, 'windows': 1}
    mu_d={}
    if mu_d_ is None:
        mu_d_ = {}
    for key, size in parameters.items():
        if not isinstance(parameter_weights[key], list):
            parameter_weights[key] = [parameter_weights[key] for i in range(size)]
        if key not in mu_d_:
            mu_d_[key] = [0 for i in range(size)]
        if not isinstance(mu_d_[key], list):
            mu_d[key] = [mu_d_[key][i] for i in range(size)]
        else:
            mu_d[key] = mu_d_[key]

    parameter_functionals = []

    if constant_part is not None:
        # sigma_d * constant_part
        parameter_functionals.append(state_functional * constant_part)
        # + 1
        parameter_functionals.append(ConstantParameterFunctional(1))

    def make_zero_expressions(parameters):
        zero_derivative_expression = {}
        for key, size in parameters.items():
            zero_expressions = np.array([], dtype='<U60')
            for l in range(size):
                zero_expressions = np.append(zero_expressions, ['0'])
            zero_expressions = np.array(zero_expressions, dtype='<U60')
            zero_derivative_expression[key] = zero_expressions
        return zero_derivative_expression

    #prepare dict
    def make_dict_zero_expressions(parameters):
        zero_dict = {}
        for key, size in parameters.items():
            zero_ = np.empty(size, dtype=dict)
            zero_dict[key] = zero_
            for l in range(size):
                zero_dict[key][l] = make_zero_expressions(parameters)
        return zero_dict

    for key, size in parameters.items():
        for i in range(size):
            weight = parameter_weights[key][i]
            derivative_expression = make_zero_expressions(parameters)
            second_derivative_expressions = make_dict_zero_expressions(parameters)
            derivative_expression[key][i] = \
                        '{}*{}**2*({}[{}]-'.format(weight,parameter_scales[key],key,i) + '{}'.format(mu_d[key][i])+')'
            second_derivative_expressions[key][i][key][i]= '{}*{}**2'.format(weight,parameter_scales[key])
            parameter_functionals.append(ExpressionParameterFunctional('{}*{}**2*0.5*({}[{}]'.format( \
                                                                        weight,parameter_scales[key],key,i) \
                                                                        +'-{}'.format(mu_d[key][i])+')**2',
                                                                        parameters,
                                                                        derivative_expressions=derivative_expression,
                                                                        second_derivative_expressions=second_derivative_expressions))
    def mapping(mu):
        ret = 0
        for f in parameter_functionals:
            ret += f.evaluate(mu)
        return ret

    def make_mapping(key, i):
        def sum_derivatives(mu):
            ret = 0
            for f in parameter_functionals:
                ret += f.d_mu(key, i).evaluate(mu)
            return ret
        return sum_derivatives

    def make_second_mapping(key, i):
        def sum_second_derivatives(mu):
            ret = 0
            for f in parameter_functionals:
                ret += f.d_mu(key, i).d_mu(key, i).evaluate(mu)
            return ret
        return sum_second_derivatives

    def make_zero_mappings(parameters):
        zero_derivative_mappings = {}
        for key, size in parameters.items():
            zero_mappings = np.array([], dtype=object)
            zero_mapping = lambda mu: 0.
            for i in range(size):
                zero_mappings = np.append(zero_mappings, [zero_mapping])
            zero_derivative_mappings[key] = zero_mappings
        return zero_derivative_mappings

    #prepare dict
    def make_dict_zero_mapping(parameters):
        zero_dict = {}
        for key, size in parameters.items():
            zero_ = np.empty(size, dtype=dict)
            zero_dict[key] = zero_
            for l in range(size):
                zero_dict[key][l] = make_zero_mappings(parameters)
        return zero_dict

    derivative_mappings = make_zero_mappings(parameters)
    for key, size in parameters.items():
        for i in range(size):
            derivative_mappings[key][i] = make_mapping(key,i)

    second_derivative_mappings = make_dict_zero_mapping(parameters)
    for key, size in parameters.items():
        for i in range(size):
            second_derivative_mappings[key][i][key][i] = make_second_mapping(key,i)

    output_coefficient = GenericParameterFunctional(mapping, parameters,
                                                    derivative_mappings=derivative_mappings,
                                                    second_derivative_mappings=second_derivative_mappings)
    return output_coefficient