-
Notifications
You must be signed in to change notification settings - Fork 0
/
Functions.py
74 lines (61 loc) · 2.45 KB
/
Functions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# -*- coding: utf-8 -*-
from dreal import *
import torch
import numpy as np
import random
def CheckLyapunov(x, f, V, ball_lb, ball_ub, config, epsilon):
# Given a dynamical system dx/dt = f(x,u) and candidate Lyapunov function V
# Check the Lyapunov conditions within a domain around the origin (ball_lb ≤ sqrt(∑xᵢ²) ≤ ball_ub).
# If it return unsat, then there is no state violating the conditions.
ball= Expression(0)
lie_derivative_of_V = Expression(0)
for i in range(len(x)):
ball += x[i]*x[i]
lie_derivative_of_V += f[i]*V.Differentiate(x[i])
ball_in_bound = logical_and(ball_lb*ball_lb <= ball, ball <= ball_ub*ball_ub)
# Constraint: x ∈ Ball → (V(c, x) > 0 ∧ Lie derivative of V <= 0)
condition = logical_and(logical_imply(ball_in_bound, V >= 0),
logical_imply(ball_in_bound, lie_derivative_of_V <= epsilon))
return CheckSatisfiability(logical_not(condition),config)
def CheckdVdx(x, V, ball_ub, config, M):
# Given a candidate Lyapunov function V, check the Lipschitz constant within a domain around the origin (sqrt(∑xᵢ²) ≤ ball_ub).
# If it return unsat, then there is no state violating the conditions.
ball= Expression(0)
derivative_of_V = Expression(0)
for i in range(len(x)):
ball += x[i]*x[i]
derivative_of_V += V.Differentiate(x[i])*V.Differentiate(x[i])
ball_in_bound = logical_and(ball <= ball_ub*ball_ub)
# Constraint: x ∈ Ball → partial derivative of V <= M
condition = logical_imply(ball_in_bound, derivative_of_V <= M)
return CheckSatisfiability(logical_not(condition),config)
def AddCounterexamples(x,CE,N):
# Adding CE back to sample set
c = []
nearby= []
for i in range(CE.size()):
c.append(CE[i].mid())
lb = CE[i].lb()
ub = CE[i].ub()
nearby_ = np.random.uniform(lb,ub,N)
nearby.append(nearby_)
for i in range(N):
n_pt = []
for j in range(x.shape[1]):
n_pt.append(nearby[j][i])
x = torch.cat((x, torch.tensor([n_pt])), 0)
return x
def dtanh(s):
# Derivative of activation
return 1.0 - s**2
def Tune(x):
# Circle function values
y = []
for r in range(0,len(x)):
v = 0
for j in range(x.shape[1]):
v += x[r][j]**2
f = [torch.sqrt(v)]
y.append(f)
y = torch.tensor(y)
return y