Exemplo n.º 1
0
    def get_lines_set(self):
        'compute range of discrete reach set, i.e.,  x_min[i] <= x[i] <= x_max[i]'

        assert self.alpha_range is not None and self.beta_range is not None, 'set perturbation parameters'
        assert self.Vn is not None and self.ln is not None, 'empty set to get min max'

        n = self.Vn.shape[0]
        min_vec = np.zeros((n, ), dtype=float)
        max_vec = np.zeros((n, ), dtype=float)
        min_points = []
        max_points = []
        line_set_list = []

        for i in xrange(0, n):
            min_func = Functions.U_n_i_func(self.Vn[i, 0], self.ln[i, 0])
            max_func = Functions.U_n_i_func(-self.Vn[i, 0], -self.ln[i, 0])

            x0 = [self.alpha_range[0], self.beta_range[0]]
            bnds = (self.alpha_range, self.beta_range)
            min_res = minimize(
                min_func,
                x0,
                method='L-BFGS-B',
                bounds=bnds,
                tol=1e-10,
                options={
                    'disp': False
                })  # add options={'disp': True} to display optimization result
            max_res = minimize(
                max_func,
                x0,
                method='L-BFGS-B',
                bounds=bnds,
                tol=1e-10,
                options={'disp': False}
            )  # add  options={'disp': True} to display optimization result

            if min_res.status == 0:
                min_vec[i] = min_res.fun
                min_points.append(min_res.x)
            else:
                print "\nmin_res.status = {}".format(min_res.status)
                print "\nminimization message: {}".format(min_res.message)
                raise ValueError('minimization fail!')

            if max_res.status == 0:
                max_vec[i] = -max_res.fun
                max_points.append(max_res.x)
            else:
                print "\nmax_res.status = {}".format(max_res.status)
                print "\nmaximization message: {}".format(max_res.message)
                raise ValueError('maximization fail!')

            line = LineSet()
            line.set_bounds(min_vec[i], max_vec[i])
            line_set_list.append(line)

        return line_set_list, min_vec, min_points, max_vec, max_points
Exemplo n.º 2
0
    def get_trace_func(self, alpha_value, beta_value, x_value):
        'return a trace function for specific values of alpha and beta'

        assert isinstance(alpha_value, float)
        assert isinstance(beta_value, float)
        m = len(self.xlist)
        assert isinstance(
            x_value, float) and self.xlist[0] <= x_value <= self.xlist[m - 1]

        for i in xrange(1, m):
            if self.xlist[i - 1] < x_value <= self.xlist[i]:
                delta_a = self.delta_a_vec[i]
                delta_b = self.delta_b_vec[i]
                delta_c = self.delta_c_vec[i]
                delta_d = self.delta_d_vec[i]
                delta_gamma_a = self.delta_gamma_a_vec[i]
                delta_gamma_b = self.delta_gamma_b_vec[i]
                delta_gamma_c = self.delta_gamma_c_vec[i]
                delta_gamma_d = self.delta_gamma_d_vec[i]

                break

        trace_func = Functions.trace_func(self.step, delta_a, delta_b, delta_gamma_a, delta_gamma_b,
                                          delta_c, delta_d, delta_gamma_c, delta_gamma_d, alpha_value, beta_value, x_value)

        return trace_func
Exemplo n.º 3
0
    def get_init_cond(x):
        'get initial condition from initial condition function'

        # x is list of discreted mesh points, for example x = [0 , 0.1, 0.2,
        # .., 0.9, 1]
        assert isinstance(x, list)
        assert len(x) >= 3, 'len(x) = {} should be >= 3'.format(len(x))

        n = len(x) - 2
        u0 = lil_matrix((2*n, 1), dtype=float)
        _, init_func = Functions.init_func()

	source_f = Function('func')
	source_f = cos(y)
	f = lambdify(y, source_f)

        for i in xrange(0, n):
            v = x[i + 1]
            u0[i, 0] = init_func(v)


	for i in xrange(0, n):
	    v = x[i + 1]
	    u0[i + n, 0] = f(v)

        return u0.tocsc()
Exemplo n.º 4
0
    def load_assembler(x, x_dom, time_step, current_step):
        'compute load vector for 1D problem'

        # x is list of discretized mesh points for example x = [0 , 0.1, 0.2, .., 0.9, 1]
        # y is a variable that used to construct the f * phi function
        # the input function is defined in engine.functions.Functions class
        # x_dom = [x1, x2] defines the domain where the input function effect,
        # t_dom = (0 <= t<= time_step))
        # return [b_i] = integral (f * phi_i dx), (x1 <= x <= x2))

        assert isinstance(x, list)
        assert isinstance(x_dom, list)

        assert len(x) > 3, 'len(x) should >= 3'
        assert len(x_dom) == 2, 'len(f_domain) should be 2'
        assert (x[0] <= x_dom[0]) and (x_dom[0] <= x_dom[1]) and (
            x_dom[1] <= x[len(x) - 1]), 'inconsistent domain'
	assert current_step >= 1, 'current_step < 1'

        for i in xrange(0, len(x) - 2):
            assert isinstance(
                x[i], float), 'x[{}] should be float type'.format(i)
            assert isinstance(
                x[i + 1], float), 'x[{}] should be float type'.format(i + 1)
            assert x[i +
                     1] > x[i], 'x[i + 1] = {} should be > x[i] = {}'.format(x[i + 1], x[i])

        assert time_step > 0, 'invalid time_step'
        assert isinstance(current_step, int)

        n = len(x) - 2    # number of discretized variables

        b = lil_matrix((2*n, 1), dtype=float)
	
        for i in xrange(0, n):	#we don't intergrate among t
            seg_x = [x[i], x[i + 1], x[i + 2]]
            b[n + i, 0] = Functions.integrate_input_func_mul_phi_in_space(seg_x, x_dom, time_step * current_step)
	    b[n + i, 0] = b[n + i, 0] + Functions.integrate_input_func_mul_phi_in_space(seg_x, x_dom, time_step * (current_step - 1))
	    b[n + i, 0] = b[n + i, 0] * time_step/2

        return b.tocsc()
Exemplo n.º 5
0
    def check_safety(self, dPde, safety_specification):
        'verify safety of Pde automaton'

        assert isinstance(dPde, DPdeAutomaton)
        assert isinstance(safety_specification, SafetySpecification)

        # check consistency
        xlist = dPde.xlist
        step = dPde.time_step
        self.result.step = step
        self.result.safety_specification = safety_specification
        assert xlist is not None, 'empty dPde'
        x_range = safety_specification.x_range

        if x_range[0] < xlist[0] or x_range[1] > xlist[len(xlist) - 1]:
            raise ValueError('x_range is out of range of dPde.xlist')

        u1 = safety_specification.u1
        u2 = safety_specification.u2
        assert u1 is not None or u2 is not None, 'u1 and u2 are both None'
        x1 = safety_specification.x_range[0]
        x2 = safety_specification.x_range[1]
        T1 = safety_specification.t_range[0]
        T2 = safety_specification.t_range[1]

        end_time_step = int(math.ceil(T2 / step))
        start_time_step = int(math.floor(T1 / step))

        m = len(xlist)
        for i in xrange(1, m):
            if xlist[i - 1] <= x1 < xlist[i]:
                start_point = i - 1
                break
            elif x1 == xlist[i]:
                start_point = i
                break

        for i in xrange(0, m):
            if xlist[m - 2 - i] < x2 <= xlist[m - 1 - i]:
                end_point = m - 1 - i
                break
            elif x2 == xlist[m - 2 - i]:
                end_point = m - 2 - i
                break

        # compute continuous reachable set
        _, _, _, _, _, bloated_set = ReachSetAssembler.get_interpolationset(
            dPde, end_time_step)

        # decompose x1 x2 into list of x_range
        x_range_list = []

        for i in xrange(start_point, end_point):
            if i == start_point:
                x_range_list.append((x1, xlist[start_point + 1]))
            elif i == end_point - 1:
                x_range_list.append((xlist[end_point - 1], x2))
            elif start_point < i < end_point - 1:
                x_range_list.append((xlist[i], xlist[i + 1]))

        # decompose T1, T2 into list of t_range
        t_range_list = []
        for j in xrange(start_time_step, end_time_step + 1):
            if j == start_time_step:
                t_range_list.append((T1, (start_time_step + 1) * step))
            elif j == end_time_step:
                t_range_list.append(((end_time_step - 1) * step, T2))
            elif start_time_step < j < end_time_step:
                t_range_list.append((j * step, (j + 1) * step))

        # check safety
        print "\nstart_time_step = {}".format(start_time_step)
        print "\nend_time_step = {}".format(end_time_step)
        for j in xrange(start_time_step, end_time_step):
            print "\n j = {}".format(j)
            bl_set = bloated_set[j]
            time_range = t_range_list[j - start_time_step]
            print "\ntime_range = {}".format(time_range)

            for i in xrange(start_point, end_point):
                print "\ni = {}".format(i)
                x_range = x_range_list[i - start_point]
                print "\nx_range = {}".format(x_range)

                min_func = Functions.intpl_in_time_and_space_func(
                    step, bl_set.delta_a_vec[i], bl_set.delta_b_vec[i],
                    bl_set.delta_gamma_a_vec[i], bl_set.delta_gamma_b_vec[i],
                    bl_set.delta_c_vec[i], bl_set.delta_d_vec[i],
                    bl_set.delta_gamma_c_vec[i], bl_set.delta_gamma_d_vec[i])

                max_func = Functions.intpl_in_time_and_space_func(
                    step, -bl_set.delta_a_vec[i], -bl_set.delta_b_vec[i],
                    -bl_set.delta_gamma_a_vec[i], -bl_set.delta_gamma_b_vec[i],
                    -bl_set.delta_c_vec[i], -bl_set.delta_d_vec[i],
                    -bl_set.delta_gamma_c_vec[i], -bl_set.delta_gamma_d_vec[i])

                x0 = [
                    time_range[0], x_range[0], dPde.alpha_range[0],
                    dPde.beta_range[0]
                ]

                bnds = (time_range, x_range, dPde.alpha_range, dPde.beta_range)

                min_res = minimize(
                    min_func,
                    x0,
                    method='L-BFGS-B',
                    bounds=bnds,
                    tol=1e-10,
                    options={'disp': False}
                )  # add options={'disp': True} to display optimization result
                max_res = minimize(
                    max_func,
                    x0,
                    method='L-BFGS-B',
                    bounds=bnds,
                    tol=1e-10,
                    options={'disp': False}
                )  # add  options={'disp': True} to display optimization result

                min_points = []
                max_points = []
                if min_res.status == 0:
                    min_value = min_res.fun
                    min_points.append(min_res.x)
                else:
                    print "\nmin_res.status = {}".format(min_res.status)
                    print "\nminimization message: {}".format(min_res.message)
                    raise ValueError(
                        'minimization for interpolation function fail!')

                if max_res.status == 0:
                    max_value = -max_res.fun
                    max_points.append(max_res.x)
                else:
                    print "\nmax_res.status = {}".format(max_res.status)
                    print "\nmaximization message: {}".format(max_res.message)
                    raise ValueError(
                        'maximization for interpolation function fail!')

                if u1 is not None and u2 is not None:
                    if min_value < u1:
                        self.result.status = 'Unsafe'
                        self.result.unsafe_u_point = min_value
                        feas_sol = min_points
                        break
                    elif max_value > u2:
                        self.result.status = 'Unsafe'
                        self.result.unsafe_u_point = max_value
                        feas_sol = max_points
                        break
                elif u1 is None and u2 is not None:
                    if max_value > u2:
                        self.result.status = 'Unsafe'
                        self.result.unsafe_u_point = max_value
                        feas_sol = max_points
                        break
                elif u1 is not None and u2 is None:
                    if min_value < u1:
                        self.result.status = 'Unsafe'
                        self.result.unsafe_u_point = min_value
                        feas_sol = min_points
                        break

            if self.result.status == 'Unsafe':
                fs = feas_sol[0]
                self.result.unsafe_time_point = fs[0]
                self.result.unsafe_x_point = fs[1]
                alpha_value = fs[2]
                beta_value = fs[3]
                print "\nfeas_solution = {}".format(feas_sol)
                break

        # return safe or unsafe and unsafe trace which is a list of function of t
        self.result.unsafe_trace_funcs = []
        if self.result.status == 'Unsafe':
            for j in xrange(0, end_time_step):
                bl_set = bloated_set[j]
                self.result.unsafe_trace_funcs.append(
                    bl_set.get_trace_func(alpha_value, beta_value,
                                          self.result.unsafe_x_point))
        else:
            self.result.status = 'Safe'

        return self.result
Exemplo n.º 6
0
    def get_2D_boxes(self, alpha_range, beta_range):
        'get box contain all value of U_n(x) and min-max value of U_n(x)'

        assert self.a_vec is not None and self.b_vec is not None and self.c_vec is not None and self.d_vec is not None
        assert isinstance(alpha_range, tuple)
        assert isinstance(beta_range, tuple)
        assert len(alpha_range) == len(beta_range) == 2, 'invalid parameters'
        assert alpha_range[0] <= alpha_range[1]
        assert beta_range[0] <= beta_range[1]

        n = self.a_vec.shape[0]

        a_vec = self.a_vec
        b_vec = self.b_vec
        c_vec = self.c_vec
        d_vec = self.d_vec

        # minimum value of Un(x) at each segment
        min_vec = np.zeros((n,), dtype=float)
        # minimum points [x_min, alpha_min, beta_min]
        min_points = np.zeros((n, 3), dtype=float)
        # maximum value of Un(x) at each segment
        max_vec = np.zeros((n,), dtype=float)
        # maximum points [x_max, alpha_max, beta_max]
        max_points = np.zeros((n, 3), dtype=float)

        boxes_2D_list = []

        for i in xrange(0, n):
            min_func = Functions.intpl_inspace_func(
                a_vec[i], b_vec[i], c_vec[i], d_vec[i])
            max_func = Functions.intpl_inspace_func(
                -a_vec[i], -b_vec[i], -c_vec[i], -d_vec[i])
            xbounds = (self.xlist[i], self.xlist[i + 1])
            x0 = [self.xlist[i], alpha_range[0], beta_range[0]]
            bnds = (xbounds, alpha_range, beta_range)

            min_res = minimize(
                min_func,
                x0,
                method='L-BFGS-B',
                bounds=bnds,
                tol=1e-10, options={'disp': False})
            max_res = minimize(
                max_func,
                x0,
                method='L-BFGS-B',
                bounds=bnds,
                tol=1e-10, options={'disp': False})

            if min_res.status == 0:
                min_vec[i] = min_res.fun
                min_points[i, :] = min_res.x
            else:
                raise ValueError('min-optimization fail')

            if max_res.status == 0:
                max_vec[i] = -max_res.fun
                max_points[i, :] = max_res.x
            else:
                raise ValueError('max-optimization fail')

            box_2D = RectangleSet2D()
            box_2D.set_bounds(
                self.xlist[i], self.xlist[i + 1], min_vec[i], max_vec[i])
            boxes_2D_list.append(box_2D)

        return boxes_2D_list
Exemplo n.º 7
0
    def get_3D_boxes(self, alpha_range, beta_range):
        'find minimum and maximum values of interpolation set U(x, t) and 3D boxes contain all U(x,t)'

        assert self.delta_a_vec is not None, 'empty interpolation set'
        assert isinstance(alpha_range, tuple) and len(
            alpha_range) == 2 and alpha_range[0] <= alpha_range[1], 'invalid alpha_range'
        assert isinstance(beta_range, tuple) and len(
            beta_range) == 2 and beta_range[0] <= beta_range[1], 'invalid beta_range'

        m = self.delta_a_vec.shape[0]		#number of mesh points

        min_vec = np.zeros((m,), dtype=float)
        max_vec = np.zeros((m,), dtype=float)
        min_points = []
        max_points = []
        boxes_3D_list = []

        for j in xrange(0, m):
            min_func = Functions.intpl_in_time_and_space_func(
                self.step,
                self.delta_a_vec[j],
                self.delta_b_vec[j],
                self.delta_gamma_a_vec[j],
                self.delta_gamma_b_vec[j],
                self.delta_c_vec[j],
                self.delta_d_vec[j], 
                self.delta_gamma_c_vec[j],
                self.delta_gamma_d_vec[j])
            max_func = Functions.intpl_in_time_and_space_func(self.step, -
                                                              self.delta_a_vec[j], -
                                                              self.delta_b_vec[j], -
                                                              self.delta_gamma_a_vec[j], -
                                                              self.delta_gamma_b_vec[j], -
                                                              self.delta_c_vec[j], -
                                                              self.delta_d_vec[j], -
                                                              self.delta_gamma_c_vec[j], -
                                                              self.delta_gamma_d_vec[j])

            x0 = [
                (self.cur_time_step - 1) * self.step,
                self.xlist[j],
                alpha_range[0],
                beta_range[0]]
            t_bnd = (
                (self.cur_time_step - 1) * self.step,
                self.cur_time_step * self.step)
            x_bnd = (self.xlist[j], self.xlist[j + 1])
            bnds = (t_bnd, x_bnd, alpha_range, beta_range)
            min_res = minimize(
                min_func,
                x0,
                method='L-BFGS-B',
                bounds=bnds,
                tol=1e-10, options={'disp': False})    # add options={'disp': True} to display optimization result
            max_res = minimize(
                max_func,
                x0,
                method='L-BFGS-B',
                bounds=bnds,
                tol=1e-10, options={'disp': False})    # add  options={'disp': True} to display optimization result

            if min_res.status == 0:
                min_vec[j] = min_res.fun
                min_points.append(min_res.x)
            else:
                print "\nmin_res.status = {}".format(min_res.status)
                print "\nminimization message: {}".format(min_res.message)
                raise ValueError(
                    'minimization for interpolation function fail!')

            if max_res.status == 0:
                max_vec[j] = -max_res.fun
                max_points.append(max_res.x)
            else:
                print "\nmax_res.status = {}".format(max_res.status)
                print "\nmaximization message: {}".format(max_res.message)
                raise ValueError(
                    'maximization for interpolation function fail!')

            ymin = (self.cur_time_step - 1) * self.step
            ymax = (self.cur_time_step) * self.step

	    if j == 0:	
		temp1, temp2 = 0, 0
		temp3, temp4 = self.get_min_max(alpha_range, beta_range, self.d_reach_prev.Vn[j].todense(), self.d_reach_prev.ln[j].todense())
		temp5, temp6 = 0, 0
		temp7, temp8 = self.get_min_max(alpha_range, beta_range, self.d_reach_curr.Vn[j].todense(), self.d_reach_curr.ln[j].todense())
	    elif 0 < j < m - 1:
		temp1, temp2 = self.get_min_max(alpha_range, beta_range, self.d_reach_prev.Vn[j - 1].todense(), self.d_reach_prev.ln[j - 1].todense())
		temp3, temp4 = self.get_min_max(alpha_range, beta_range, self.d_reach_prev.Vn[j].todense(), self.d_reach_prev.ln[j].todense())
		temp5, temp6 = self.get_min_max(alpha_range, beta_range, self.d_reach_curr.Vn[j - 1].todense(), self.d_reach_curr.ln[j - 1].todense())
		temp7, temp8 = self.get_min_max(alpha_range, beta_range, self.d_reach_curr.Vn[j].todense(), self.d_reach_curr.ln[j].todense())
	    elif j == m - 1:
		temp1, temp2 = self.get_min_max(alpha_range, beta_range, self.d_reach_prev.Vn[j - 1].todense(), self.d_reach_prev.ln[j - 1].todense())
		temp3, temp4 = 0, 0
		temp5, temp6 = self.get_min_max(alpha_range, beta_range, self.d_reach_curr.Vn[j - 1].todense(), self.d_reach_curr.ln[j - 1].todense())
		temp7, temp8 = 0, 0


	    temp = [temp1, temp2, temp3, temp4, temp5, temp6, temp7, temp8]
	    temp.sort()
	    min_vec[j] = temp[0]
	    print "\n min is {}".format(min_vec[j])
	    max_vec[j] = temp[7]
	    print "\n max is {}".format(max_vec[j])

            box_3D = RectangleSet3D()
            box_3D.set_bounds(self.xlist[j],
                              self.xlist[j + 1],
                              ymin,
                              ymax,
                              min_vec[j],
                              max_vec[j])
            boxes_3D_list.append(box_3D)

        return boxes_3D_list
Exemplo n.º 8
0
    def load_assembler_err(x, x_dom, time_step, current_step, prev_u, cur_u):
        'compute load vector for 1D problem, we added u double dots on right hand side'

        # x is list of discretized mesh points for example x = [0 , 0.1, 0.2, .., 0.9, 1]
        # y is a variable that used to construct the f * phi function
        # the input function is defined in engine.functions.Functions class
        # x_dom = [x1, x2] defines the domain where the input function effect,
        # t_dom = (0 <= t<= time_step))
        # return [b_i] = integral (f * phi_i dx), (x1 <= x <= x2))

        assert isinstance(x, list)
        assert isinstance(x_dom, list)

        assert len(x) > 3, 'len(x) should >= 3'
        assert len(x_dom) == 2, 'len(f_domain) should be 2'
        assert (x[0] <= x_dom[0]) and (x_dom[0] <= x_dom[1]) and (
            x_dom[1] <= x[len(x) - 1]), 'inconsistent domain'
	assert current_step >= 1, 'current_step < 1'

        for i in xrange(0, len(x) - 2):
            assert isinstance(
                x[i], float), 'x[{}] should be float type'.format(i)
            assert isinstance(
                x[i + 1], float), 'x[{}] should be float type'.format(i + 1)
            assert x[i +
                     1] > x[i], 'x[i + 1] = {} should be > x[i] = {}'.format(x[i + 1], x[i])

        assert time_step > 0, 'invalid time_step'
        assert isinstance(current_step, int)

        n = len(x) - 2    # number of discretized variables
        b = lil_matrix((2*n, 1), dtype=float)

        b_t_curr = lil_matrix((n, 1), dtype=float)

        for i in xrange(0, n):
            seg_x = [x[i], x[i + 1], x[i + 2]]
            b_t_curr[i, 0] = Functions.integrate_input_func_mul_phi_in_space(seg_x, x_dom, time_step * current_step)

	s = Fem1Dw.stiff_assembler(x)

	u_value_curr = cur_u.Vn + cur_u.ln
	
	u_value_curr = u_value_curr[0 : n]

	M_inv = linalg.inv(Fem1Dw.mass_assembler(x))
	
	sec_deri_cur = M_inv * (b_t_curr - s * u_value_curr)

	b_t_prev = lil_matrix((n, 1), dtype=float)

        for i in xrange(0, n):
            seg_x = [x[i], x[i + 1], x[i + 2]]
            b_t_prev[i, 0] = Functions.integrate_input_func_mul_phi_in_space(seg_x, x_dom, time_step * (current_step - 1))

	u_value_prev = prev_u.Vn + prev_u.ln

	u_value_prev = u_value_prev[0 : n]
	
	sec_deri_prev = M_inv * (b_t_prev - s * u_value_prev)



        for i in xrange(0, n):	#we don't intergrate among t

            seg_x = [x[i], x[i + 1], x[i + 2]]

	    b[n + i, 0] = Functions.integrate_input_func_mul_phi_in_space(seg_x, x_dom, time_step * current_step) - sec_deri_cur[i, 0] * 4/3 * time_step  
	    b[n + i, 0] = b[n + i, 0] + Functions.integrate_input_func_mul_phi_in_space(seg_x, x_dom, time_step * (current_step - 1)) - sec_deri_prev[i, 0] * 4/3 * time_step  
	    b[n + i, 0] = b[n + i, 0] * time_step/2	    

        return b.tocsc()