def get_test_statistic(model, x0_I, x0_II, u_I, u_II, num_exp=1000, nu=1):
    sys_dim = len(model[0][:, 0])
    data_I = simulate_system(model, x0_I, u_I, num_exp=num_exp)
    data_II = simulate_system(model, x0_II, u_II, num_exp=num_exp)
    mmd_st = np.zeros((sys_dim, num_exp))
    mmd = np.zeros(sys_dim)
    for test_infl_on in range(sys_dim):
        for i in range(num_exp):
            mmd_st[test_infl_on,
                   i] = mmd2(data_I[sys_dim * i + test_infl_on, 1::],
                             data_II[sys_dim * i + test_infl_on, 1::])
        mmd[test_infl_on] = mmd_st[test_infl_on,
                                   0] + nu * np.std(mmd_st[test_infl_on, 1::])
    return mmd
Ejemplo n.º 2
0
def real_mmd(sys,
             test_infl_of,
             test_infl_on,
             init_cond1,
             inp_traj1,
             init_cond2=0,
             inp_traj2=0,
             num_exp=1):
    sys1 = sys
    sys2 = copy.deepcopy(sys)
    for _ in range(num_exp):
        sys1.state = init_cond1.reshape(-1, 1)
        try:
            sys2.state = init_cond2.reshape(-1, 1)
        except:
            sys2.state = copy.deepcopy(sys1.state)
            init_cond2 = init_cond1
        try:
            len(inp_traj2)
        except:
            inp_traj2 = inp_traj1
        x_st = np.zeros((len(sys1.state), inp_traj1.shape[1] + 1))
        y_st = np.zeros((len(sys1.state), inp_traj1.shape[1] + 1))
        x_st[:, 0] = init_cond1[:]
        y_st[:, 0] = init_cond2[:]
        for i in range(inp_traj1.shape[1]):
            X = np.vstack((sys1.state, inp_traj1[:, i].reshape(-1, 1)))
            Y = np.vstack((sys2.state, inp_traj2[:, i].reshape(-1, 1)))
            sys1.dynamics(inp_traj1[:, i])
            sys2.dynamics(inp_traj2[:, i])
            x_st[:, i + 1] = sys1.state[:, 0]
            y_st[:, i + 1] = sys2.state[:, 0]
        try:
            x_mult = np.hstack((x_mult, x_st))
            y_mult = np.hstack((y_mult, y_st))
        except:
            x_mult = copy.deepcopy(x_st)
            y_mult = copy.deepcopy(y_st)
    mmd = np.zeros(len(test_infl_on))
    for idx, i in enumerate(test_infl_on):
        if i == test_infl_of:
            x_mult[i, :] -= init_cond1[i]
            y_mult[i, :] -= init_cond2[i]
        mmd[idx] = mmd2(x_mult[i, :], y_mult[i, :])
    return mmd, x_st, y_st
def caus_id():
    sys = synthetic_example()
    sys_dim = len(sys.high_obs)
    inp_dim = sys.inp_dim
    # Null hypothesis: no state/input has a causal influence on any state
    caus = np.zeros((sys_dim, sys_dim + inp_dim))
    # Start with standard system identification
    sys_id_state, sys_id_inp = create_sys_id_data(sys)
    init_model = sys_id(sys_id_state, sys_id_inp)
    # Get a controller based on the initial model
    ctrl = set_point_ctrl(init_model[0], init_model[1], np.diag([1, 1, 1]),
                          np.diag([0.01, 0.01, 0.01]))
    # Start causal identification
    for test_infl_of in range(sys_dim + inp_dim):
        print("new causality test")
        if test_infl_of < sys_dim:
            print("testing influence of state ", test_infl_of)
            # Choose initial conditions as far apart as possible
            x0_I = np.zeros((sys_dim, 1))
            x0_I[test_infl_of, 0] = sys.high_obs[test_infl_of]
            x0_II = np.zeros((sys_dim, 1))
            x0_II[test_infl_of, 0] = -sys.high_obs[test_infl_of]
            # Choose input trajectory that excites the system
            u_I = np.random.uniform(-1, 1, (inp_dim, 100))
            u_II = u_I
        else:
            test_inp = test_infl_of - sys_dim
            print("testing influence of input ", test_inp)
            # Choose initial position in 0
            x0_I = np.zeros((sys_dim, 1))
            x0_II = x0_I
            # Choose different input trajectories that excite the system
            u_I = 10 * np.random.uniform(-1, 1, (inp_dim, 100))
            u_II = copy.deepcopy(u_I)
            u_I[test_inp, :] = 100 * np.random.uniform(-1, 1, 100)
            u_II[test_inp, :] = np.zeros(100)
        # Do causality experiment
        exp_data_I, exp_data_II = caus_exp(init_model, sys, x0_I, x0_II, u_I,
                                           u_II, ctrl)
        # Get model assuming variables are non-causal
        caus_model = sys_id_loc(sys_id_state, sys_id_inp, test_infl_of)
        # Get test statistic
        test_stat = get_test_statistic(caus_model,
                                       exp_data_I[:, 0].reshape(-1, 1),
                                       exp_data_II[:, 0].reshape(-1, 1),
                                       u_I,
                                       u_II,
                                       nu=3)
        print("Obtained test statistic")
        # Compute MMD and compare with test statistic
        for test_infl_on in range(sys_dim):
            if test_infl_of == test_infl_on:
                exp_data_I[test_infl_on, :] -= x0_I[test_infl_on, 0]
                exp_data_II[test_infl_on, :] -= x0_II[test_infl_on, 0]
            mmd_exp = mmd2(exp_data_I[test_infl_on, :],
                           exp_data_II[test_infl_on, :])
            if mmd_exp > test_stat[test_infl_on]:
                caus[test_infl_on, test_infl_of] = 1
        print("new causality matrix:")
        print(caus)
        sys.state = np.zeros((3, 1))
Ejemplo n.º 4
0
def predict_mmd(GPs,
                sys,
                test_infl_of,
                test_infl_on,
                init_cond1,
                inp_traj1,
                init_cond2=0,
                inp_traj2=0,
                mont=0,
                num_exp=0,
                num_var=0):
    sys1 = sys
    sys2 = copy.deepcopy(sys)
    sys1.state[:, 0] = init_cond1[:]
    # Check whether we have separate initial conditions for the two systems
    try:
        sys2.state[:, 0] = init_cond2[:]
    except:
        sys2.state = copy.deepcopy(sys1.state)
        init_cond2 = init_cond1
    # Check whether we have separate input trajectories
    try:
        len(inp_traj2)
    except:
        inp_traj2 = inp_traj1
    # Create arrays depending on whether or not we want to estimate the variance
    if num_var:
        x_st = np.zeros(
            (num_var * num_exp,
             len(sys1.state) * inp_traj1.shape[1] + len(sys1.state)))
        y_st = np.zeros(
            (num_var * num_exp,
             len(sys1.state) * inp_traj1.shape[1] + len(sys1.state)))
        x_st[:, 0:len(sys1.state)] = init_cond1[:]
        y_st[:, 0:len(sys1.state)] = init_cond2[:]
    else:
        x_st = np.zeros(
            (1, len(sys1.state) * inp_traj1.shape[1] + len(sys1.state)))
        y_st = np.zeros(
            (1, len(sys1.state) * inp_traj1.shape[1] + len(sys1.state)))
        x_st[:, 0:len(sys1.state)] = init_cond1[:]
        y_st[:, 0:len(sys1.state)] = init_cond2[:]
    # Simulate system and store results
    for i in range(inp_traj1.shape[1]):
        if num_var:
            X = np.hstack((x_st[:, i * len(sys1.state):i * len(sys1.state) +
                                len(sys1.state)],
                           np.matlib.repmat(inp_traj1[:, i], num_var * num_exp,
                                            1)))
            Y = np.hstack((y_st[:, i * len(sys1.state):i * len(sys1.state) +
                                len(sys1.state)],
                           np.matlib.repmat(inp_traj2[:, i], num_var * num_exp,
                                            1)))
        else:
            X = np.hstack((x_st[:, i * len(sys1.state):i * len(sys1.state) +
                                len(sys1.state)], inp_traj1[:,
                                                            i].reshape(1, -1)))
            Y = np.hstack((y_st[:, i * len(sys1.state):i * len(sys1.state) +
                                len(sys1.state)], inp_traj2[:,
                                                            i].reshape(1, -1)))
        for idx, GP in enumerate(GPs):
            X_tmp = np.delete(X, GP.indep_var, 1)
            Y_tmp = np.delete(Y, GP.indep_var, 1)
            if num_var:
                x_st[:, (i + 1) * len(sys1.state) +
                     idx] = x_st[:,
                                 i * len(sys1.state) + idx] + np.random.normal(
                                     GP.model.predict(X_tmp)[0],
                                     (GP.model.predict(X_tmp)[1]))[:, 0]
                y_st[:, (i + 1) * len(sys1.state) +
                     idx] = y_st[:,
                                 i * len(sys1.state) + idx] + np.random.normal(
                                     GP.model.predict(Y_tmp)[0],
                                     (GP.model.predict(Y_tmp)[1]))[:, 0]
            else:
                x_st[:, (i + 1) * len(sys1.state) +
                     idx] = x_st[:, i * len(sys1.state) +
                                 idx] + GP.model.predict(X_tmp)[0]
                y_st[:, (i + 1) * len(sys1.state) +
                     idx] = y_st[:, i * len(sys1.state) +
                                 idx] + GP.model.predict(Y_tmp)[0]
    # Calculate MMD
    if num_var:
        mmd = np.zeros((num_var, len(test_infl_on)))
        for idx, i in enumerate(test_infl_on):
            if i == test_infl_of:
                x_st[:, i::len(sys1.state)] -= init_cond1[i]
                y_st[:, i::len(sys1.state)] -= init_cond2[i]
            for j in range(num_var):
                mmd[j, idx] = mmd2(
                    x_st[num_exp * j:num_exp * j + num_exp,
                         i::len(sys1.state)].flatten(),
                    y_st[num_exp * j:num_exp * j + num_exp,
                         i::len(sys1.state)].flatten())
        mmd = np.std(mmd, axis=0)
    else:
        mmd = np.zeros(len(test_infl_on))
        for idx, i in enumerate(test_infl_on):
            if i == test_infl_of:
                x_st[:, i::len(sys1.state)] -= init_cond1[i]
                y_st[:, i::len(sys1.state)] -= init_cond2[i]
            mmd[idx] = mmd2(x_st[:, i::len(sys1.state)].flatten(),
                            y_st[:, i::len(sys1.state)].flatten())
    return mmd, x_st, y_st