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
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
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()
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()
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
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
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
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()