Ejemplo n.º 1
0
def main():
    ## set root directory
    data_root = "../data/global_flow"
    save_root = "results/global_flow"

    # make directory
    if not os.path.exists(save_root):
        os.mkdir(save_root)

    ## set data
    Tf = 1000  # length of time-series
    N = 30  # widht, height of images
    dtype = "float32"
    obs = xp.asarray(np.load(os.path.join(data_root, "obs.npy")), dtype=dtype)
    true_xp = xp.asarray(np.load(os.path.join(data_root, "true.npy")),
                         dtype=dtype)

    ## set data for kalman filter
    bg_value = 20
    skip = 1  # downsampling
    Nf = int(N / skip)  # Number of lines after skip
    obs = obs[:Tf, ::skip, ::skip].reshape(Tf, -1)
    true_xp = true_xp[:Tf, ::skip, ::skip].reshape(Tf, -1) + bg_value
    boundary = xp.zeros((Nf, Nf), dtype=bool)
    boundary[0] = True
    boundary[-1] = True
    boundary[:, 0] = True
    boundary[:, -1] = True
    boundary = boundary.reshape(-1)

    ## set parameters
    d = 1  # number of adjacency element
    sigma_initial = 0  # standard deviation of normal distribution for random making
    update_interval = 10  # update interval for LSLOCK
    llock_update_interval = 50  # update interval for LLOCK
    estimation_mode = "forward"
    eta = 0.8  # learning rate
    cutoff = 1.0  # cutoff distance for update of transition matrix
    sigma = 0.2  # standard deviation of gaussian noise
    Q = sigma**2 * xp.eye(Nf * Nf)
    R = sigma**2 * xp.eye(Nf * Nf)  # Nf x nlines

    ## record list
    mse_record = xp.zeros((2, 4, Tf))
    mae_record = xp.zeros((2, 4, Tf))
    time_record = xp.zeros((2, 3))

    all_start_time = time.time()

    ### Execute
    F_initial = xp.eye(Nf * Nf)  # identity
    A = xp.asarray(parametric_matrix_cyclic_2d(Nf, d), dtype="int32")

    ## Kalman Filter
    filtered_value = xp.zeros((Tf, Nf * Nf))
    kf = KalmanFilter(transition_matrix=F_initial,
                      transition_covariance=Q,
                      observation_covariance=R,
                      initial_mean=obs[0],
                      dtype=dtype)
    for t in range(Tf):
        filtered_value[t] = kf.forward_update(t, obs[t], return_on=True)
    xp.save(os.path.join(save_root, "kf_states.npy"), filtered_value)

    ## LLOCK
    llock_save_dir = os.path.join(save_root, "llock")
    if not os.path.exists(llock_save_dir):
        os.mkdir(llock_save_dir)

    print("LLOCK : d={}, update_interval={}, eta={}, cutoff={}".format(
        d, llock_update_interval, eta, cutoff))
    llock = LocalLOCK(observation=obs,
                      transition_matrix=F_initial,
                      transition_covariance=Q,
                      observation_covariance=R,
                      initial_mean=obs[0],
                      adjacency_matrix=A,
                      dtype=dtype,
                      estimation_length=llock_update_interval,
                      estimation_interval=llock_update_interval,
                      eta=eta,
                      cutoff=cutoff,
                      save_dir=llock_save_dir,
                      estimation_mode=estimation_mode,
                      use_gpu=False)
    start_time = time.time()
    llock.forward()
    time_record[0, 0] = time.time() - start_time
    time_record[0, 1] = llock.times[3]
    time_record[0, 2] = llock.times[3] / llock.times[4]
    print("LLOCK times : {}".format(time.time() - start_time))

    ## LSLOCK
    lslock_save_dir = os.path.join(save_root, "lslock")
    if not os.path.exists(lslock_save_dir):
        os.mkdir(lslock_save_dir)

    print("LSLOCK : d={}, update_interval={}, eta={}, cutoff={}".format(
        d, update_interval, eta, cutoff))
    lslock = LSLOCK(observation=obs,
                    transition_matrix=F_initial,
                    transition_covariance=Q,
                    observation_covariance=R,
                    initial_mean=obs[0],
                    parameter_matrix=A,
                    dtype=dtype,
                    estimation_length=update_interval,
                    estimation_interval=update_interval,
                    eta=eta,
                    cutoff=cutoff,
                    save_dir=lslock_save_dir,
                    estimation_mode=estimation_mode,
                    method="gridwise",
                    use_gpu=False)
    start_time = time.time()
    lslock.forward()
    time_record[1, 0] = time.time() - start_time
    time_record[1, 1] = lslock.times[3]
    time_record[1, 2] = lslock.times[3] / lslock.times[4]
    print("LSLOCK times : {}".format(time.time() - start_time))

    # record error infromation
    area_list = [xp.ones((Nf * Nf), dtype=bool), ~boundary]
    for r, area in enumerate(area_list):
        for t in range(Tf):
            mse_record[r, 0, t] = mean_squared_error(
                lslock.get_filtered_value()[t][area], true_xp[t][area])
            mae_record[r, 0, t] = mean_absolute_error(
                lslock.get_filtered_value()[t][area], true_xp[t][area])
            mse_record[r, 1, t] = mean_squared_error(
                llock.get_filtered_value()[t][area], true_xp[t][area])
            mae_record[r, 1, t] = mean_absolute_error(
                llock.get_filtered_value()[t][area], true_xp[t][area])
            mse_record[r, 2, t] = mean_squared_error(filtered_value[t][area],
                                                     true_xp[t][area])
            mae_record[r, 2, t] = mean_absolute_error(filtered_value[t][area],
                                                      true_xp[t][area])
            mse_record[r, 3, t] = mean_squared_error(obs[t][area],
                                                     true_xp[t][area])
            mae_record[r, 3, t] = mean_absolute_error(obs[t][area],
                                                      true_xp[t][area])

    ## save error-record
    if True:
        xp.save(os.path.join(save_root, "time_record.npy"), time_record)
        xp.save(os.path.join(save_root, "mse_record.npy"), mse_record)
        xp.save(os.path.join(save_root, "mae_record.npy"), mae_record)

    # mse_record = np.load(os.path.join(save_root, "mse_record.npy"))

    fig, ax = plt.subplots(1, 1, figsize=(8, 5))
    for i, label in enumerate(["LSLOCK", "LLOCK", "KF", "observation"]):
        ax.plot(np.sqrt(mse_record[0, i]), label=label, lw=2)
    ax.set_xlabel("Timestep", fontsize=12)
    ax.set_ylabel("RMSE", fontsize=12)
    ax.legend(fontsize=15)
    fig.savefig(os.path.join(save_root, "rmse.png"), bbox_to_inches="tight")

    ## short-term prediction
    color_list = ["r", "g", "b", "m", "y"]
    threshold = 200
    pred_state = xp.zeros((Tf, Nf * Nf))
    llock_pred_state = xp.zeros((Tf, Nf * Nf))
    pred_mse = mse_record[0].copy()

    s = threshold // update_interval
    F = np.load(
        os.path.join(lslock_save_dir, "transition_matrix_{:03}.npy".format(s)))
    state = np.load(os.path.join(lslock_save_dir, "states.npy"))[threshold]
    pred_state[threshold] = state.reshape(-1)
    for t in range(threshold, Tf - 1):
        pred_state[t + 1] = F @ pred_state[t]

    s = threshold // llock_update_interval
    F = np.load(
        os.path.join(llock_save_dir, "transition_matrix_{:02}.npy".format(s)))
    llock_state = np.load(os.path.join(llock_save_dir,
                                       "states.npy"))[threshold]
    llock_pred_state[threshold] = llock_state.reshape(-1)
    for t in range(threshold, Tf - 1):
        llock_pred_state[t + 1] = F @ llock_pred_state[t]

    kf_state = np.load(os.path.join(save_root, "kf_states.npy"))[threshold]
    for t in range(threshold, Tf):
        pred_mse[0, t] = mean_squared_error(pred_state[t], true_xp[t])
        pred_mse[1, t] = mean_squared_error(llock_pred_state[t], true_xp[t])
        pred_mse[2, t] = mean_squared_error(kf_state.reshape(-1), true_xp[t])
        pred_mse[3, t] = mean_squared_error(obs[threshold], true_xp[t])

    convlstm_mse = np.load(
        os.path.join(save_root, "convlstm",
                     "convlstm_mse.npy"))  # epoch//save_epoch x 10
    fig, ax = plt.subplots(1, 1, figsize=(8, 5))
    low = threshold - 4
    up = threshold + 6
    lw = 2
    ax.axvline(threshold, c="k", lw=lw, ls=":")
    for i, label in enumerate(["LSLOCK", "LLOCK", "KF", "observation"]):
        ax.plot(range(low, up),
                np.sqrt(pred_mse[i, low:up]),
                lw=lw,
                ls="--",
                c=color_list[i])
        ax.plot(range(low, threshold + 1),
                np.sqrt(mse_record[0, i, low:threshold + 1]),
                label=label,
                lw=lw,
                c=color_list[i])
    ax.plot(range(threshold, up),
            np.sqrt(convlstm_mse[400 // 50, :len(range(up - threshold))]),
            label="ConvLSTM",
            lw=lw,
            c=color_list[4])
    ax.set_xlabel("Timestep", fontsize=12)
    ax.set_ylabel("RMSE", fontsize=12)
    ax.legend(bbox_to_anchor=(1.05, 1.0), loc="upper left", fontsize=15)
    fig.savefig(os.path.join(save_root, "prediction.png"), bbox_inches="tight")

    all_execute_time = int(time.time() - all_start_time)
    print("all time (sec): {} sec".format(all_execute_time))
    print("all time (min): {} min".format(int(all_execute_time // 60)))
    print("all time (hour): {} hour + {} min".format(
        int(all_execute_time // 3600), int((all_execute_time // 60) % 60)))
Ejemplo n.º 2
0
def main():
    ## set root directory
    data_root = "../data/object_moving"
    save_root = "results/object_moving"
    

    # make directory
    if not os.path.exists(save_root):
        os.mkdir(save_root)


    ## set seed
    seed = 121
    xp.random.seed(seed)
    print("Set seed number {}".format(seed))


    ## set data
    Tf = 100  # length of time-series
    N = 25  # widht, height of images
    dtype = "float32"
    obs = xp.asarray(np.load(os.path.join(data_root, "obs.npy")), dtype=dtype)
    true_xp = xp.asarray(np.load(os.path.join(data_root, "true.npy")), dtype=dtype)


    ## set data for kalman filter
    skip = 1  # downsampling
    bg_value = 20  # background value
    Nf = int(N/skip)  # Number of lines after skip
    obs = obs[:Tf, ::skip, ::skip].reshape(Tf, -1)
    true_xp = true_xp[:Tf, ::skip, ::skip].reshape(Tf, -1) + bg_value

    ## set parameters
    d = 1 # number of adjacency element
    advance = True
    sigma_initial = 0 # standard deviation of normal distribution for random making
    update_interval = 1 # update interval
    eta = 1.0 # learning rate
    cutoff = 1.0 # cutoff distance for update of transition matrix
    sigma = 0.2  # standard deviation of gaussian noise
    Q = sigma**2 * xp.eye(Nf*Nf)
    R = sigma**2 * xp.eye(Nf*Nf) # Nf x nlines


    ## record list
    mse_record = xp.zeros((3, Tf))
    mae_record = xp.zeros((3, Tf))
    time_record = xp.zeros(3)

    all_start_time = time.time()

    ### Execute
    F_initial = xp.eye(Nf*Nf) # identity
    A = xp.asarray(parametric_matrix_2d(Nf, Nf, d), dtype="int32")

    ## Kalman Filter
    filtered_value = xp.zeros((Tf, Nf*Nf))
    kf = KalmanFilter(transition_matrix = F_initial,
                         transition_covariance = Q, observation_covariance = R,
                         initial_mean = obs[0], dtype = dtype)
    for t in range(Tf):
        filtered_value[t] = kf.forward_update(t, obs[t], return_on=True)
    xp.save(os.path.join(save_root, "kf_states.npy"), filtered_value)
                            
    ## LLOCK
    save_dir = os.path.join(save_root, "llock")
    if not os.path.exists(save_dir):
        os.mkdir(save_dir)

    print("SLOCK : d={}, update_interval={}, eta={}, cutoff={}".format(
        d, update_interval, eta, cutoff))
    slock = SpatiallyUniformLOCK(observation = obs, 
                     transition_matrix = F_initial,
                     transition_covariance = Q, 
                     observation_covariance = R,
                     initial_mean = obs[0], 
                     localization_matrix = A,
                     dtype = dtype,
                     update_interval = update_interval,
                     eta = eta, 
                     cutoff = cutoff,
                     save_dir = save_dir,
                     advance_mode = advance,
                     use_gpu = False)
    start_time = time.time()
    slock.forward()
    time_record[0] = time.time() - start_time
    time_record[1] = slock.times[3]
    time_record[2] = slock.times[3] / slock.times[4]
    print("SLOCK times : {}".format(time.time() - start_time))

    # record error infromation
    for t in range(Tf):
        mse_record[0,t] = mean_squared_error(
                                slock.get_filtered_value()[t],
                                true_xp[t])
        mae_record[0,t] = mean_absolute_error(
                                slock.get_filtered_value()[t],
                                true_xp[t])
        mse_record[1,t] = mean_squared_error(
                                filtered_value[t],
                                true_xp[t])
        mae_record[1,t] = mean_absolute_error(
                                filtered_value[t],
                                true_xp[t])
        mse_record[2,t] = mean_squared_error(
                                obs[t],
                                true_xp[t])
        mae_record[2,t] = mean_absolute_error(
                                obs[t],
                                true_xp[t])

    ## save error-record
    if True:
        xp.save(os.path.join(save_root, "time_record.npy"), time_record)
        xp.save(os.path.join(save_root, "mse_record.npy"), mse_record)
        xp.save(os.path.join(save_root, "mae_record.npy"), mae_record)

    # mse_record = np.load(os.path.join(save_root, "mse_record.npy"))

    fig, ax = plt.subplots(1,1,figsize=(8,5))
    for i, label in enumerate(["SLOCK", "KF", "observation"]):
        ax.plot(np.sqrt(mse_record[i]), label=label, lw=2)
    ax.set_xlabel("Timestep", fontsize=12)
    ax.set_ylabel("RMSE", fontsize=12)
    ax.legend(fontsize=15)
    fig.savefig(os.path.join(save_root, "rmse.png"), bbox_to_inches="tight")


    ## substantial mse
    def translation_matrix4(W=10, H=10, direction="right", cyclic=False):
        F = xp.zeros((W*H, W*H))
        if direction=="right":
            F_block = xp.diag(xp.ones(W-1), -1)
            if cyclic:
                F_block[0, -1] = 1
            for i in range(H):
                F[i*W:(i+1)*W, i*W:(i+1)*W] = F_block
        elif direction=="left":
            F_block = xp.diag(xp.ones(W-1), 1)
            if cyclic:
                F_block[-1, 0] = 1
            for i in range(H):
                F[i*W:(i+1)*W, i*W:(i+1)*W] = F_block
        elif direction=="up":
            F_block = xp.eye(W)
            for i in range(H-1):
                F[i*W:(i+1)*W, (i+1)*W:(i+2)*W] = F_block
            if cyclic:
                F[(H-1)*W:H*W, 0:W] = F_block
        elif direction=="down":
            F_block = xp.eye(W)
            for i in range(H-1):
                F[(i+1)*W:(i+2)*W, i*W:(i+1)*W] = F_block
            if cyclic:
                F[0:W, (H-1)*W:H*W] = F_block
        return F

    def translation_matrix8(W=10, H=10, direction="right", cyclic=False):
        if direction in ["right", "left", "up", "down"]:
            F = translation_matrix4(W, H, direction, cyclic)
        elif direction in ["up-right", "up-left", "down-right", "down-left"]:
            direction1, direction2 = direction.split("-")
            F = translation_matrix4(W, H, direction1, cyclic) @ translation_matrix4(W, H, direction2, cyclic)
        return F

    direction_count = 0
    directions = ["right", "up", "left", "down", "right", "up", "up-right","left",
           "down-right","up","down-left","up","down-right"]
    direction_changes = [5,10,20,30,35,40,45,55,65,75,85,95,1000]
    Ftrue = translation_matrix8(Nf, Nf, directions[0])


    mean_error = np.zeros((2, Tf//update_interval-1))
    for t in range(Tf//update_interval-1):
        fvalue = np.load(os.path.join(save_dir, "transition_matrix_{:03}.npy".format(t)))

        if t+1>=direction_changes[direction_count]:
            direction_count += 1
            Ftrue = translation_matrix8(Nf, Nf, directions[direction_count], True)

        mean_error[0,t] = np.sqrt(np.power(np.absolute(fvalue - Ftrue)[A.astype(bool) & ~Ftrue.astype(bool)], 2).mean())
        mean_error[1,t] = np.sqrt(np.power(np.absolute(fvalue - Ftrue)[A.astype(bool) & Ftrue.astype(bool)], 2).mean())

    fig, ax = plt.subplots(1,1,figsize=(12,5))
    lw = 2
    for i in range(2):
        ax.plot(update_interval * np.array(range(Tf//update_interval-1)), mean_error[i], 
                   label="true={}".format(i), lw=lw)
    for mc in direction_changes[:-1]:
        ax.axvline(mc, ls="--", color="navy", lw=1)
    ax.set_xlabel("Timestep", fontsize=15)
    ax.set_ylabel("SRMSE", fontsize=15)
    ax.set_yscale("log")
    ax.legend(fontsize=12)
    ax.tick_params(labelsize=12)
    directions_for_print = ["right", " up", "    left", "    down", "right", "  up", "up-right","      left",
           " down-right","      up","  down-left","       up"," down-right"]
    fig.text(0.09, 0, "Direction: ", fontsize=10)
    for kk, direction, mc in zip(range(len(directions)), directions_for_print, [0] + direction_changes[:-1]):
        fig.text(0.16 + mc*0.0071, 0, direction, fontsize=10)
    fig.savefig(os.path.join(save_root, "srmse.png"), bbox_inches="tight")


    all_execute_time = int(time.time() - all_start_time)
    print("all time (sec): {} sec".format(all_execute_time))
    print("all time (min): {} min".format(int(all_execute_time//60)))
    print("all time (hour): {} hour + {} min".format(int(all_execute_time//3600), int((all_execute_time//60)%60)))
Ejemplo n.º 3
0
def main():
    ## set root directory
    data_root = "../data/global_flow"
    save_root = "results/global_flow"

    # make directory
    if not os.path.exists(save_root):
        os.mkdir(save_root)

    ## set seed
    seed = 121
    xp.random.seed(seed)
    print("Set seed number {}".format(seed))

    ## set data
    Tf = 1000  # length of time-series
    N = 30  # widht, height of images
    dtype = "float32"
    obs = xp.asarray(np.load(os.path.join(data_root, "obs.npy")), dtype=dtype)
    true_xp = xp.asarray(np.load(os.path.join(data_root, "true.npy")),
                         dtype=dtype)

    ## set data for kalman filter
    skip = 1  # downsampling
    bg_value = 20  # background value
    Nf = int(N / skip)  # Number of lines after skip
    obs = obs[:Tf, ::skip, ::skip].reshape(Tf, -1)
    true_xp = true_xp[:Tf, ::skip, ::skip].reshape(Tf, -1) + bg_value
    boundary = xp.zeros((Nf, Nf), dtype=bool)
    boundary[0] = True
    boundary[-1] = True
    boundary[:, 0] = True
    boundary[:, -1] = True
    boundary = boundary.reshape(-1)

    ## set parameters
    d = 1  # number of adjacency element
    advance = True
    sigma_initial = 0  # standard deviation of normal distribution for random making
    update_interval = 50  # update interval
    eta = 0.8  # learning rate
    cutoff = 1.0  # cutoff distance for update of transition matrix
    sigma = 0.2  # standard deviation of gaussian noise
    Q = sigma**2 * xp.eye(Nf * Nf)
    R = sigma**2 * xp.eye(Nf * Nf)  # Nf x nlines

    ## record list
    mse_record = xp.zeros((2, 3, Tf))
    mae_record = xp.zeros((2, 3, Tf))
    time_record = xp.zeros(3)

    all_start_time = time.time()

    ### Execute
    F_initial = xp.eye(Nf * Nf)  # identity
    A = xp.asarray(adjacency_matrix_cyclic_2d(Nf, d), dtype="int32")

    ## Kalman Filter
    filtered_value = xp.zeros((Tf, Nf * Nf))
    kf = KalmanFilter(transition_matrix=F_initial,
                      transition_covariance=Q,
                      observation_covariance=R,
                      initial_mean=obs[0],
                      dtype=dtype)
    for t in range(Tf):
        filtered_value[t] = kf.forward_update(t, obs[t], return_on=True)
    xp.save(os.path.join(save_root, "kf_states.npy"), filtered_value)

    ## LLOCK
    save_dir = os.path.join(save_root, "llock")
    if not os.path.exists(save_dir):
        os.mkdir(save_dir)

    print("LLOCK : d={}, update_interval={}, eta={}, cutoff={}".format(
        d, update_interval, eta, cutoff))
    llock = LocalLOCK(observation=obs,
                      transition_matrix=F_initial,
                      transition_covariance=Q,
                      observation_covariance=R,
                      initial_mean=obs[0],
                      adjacency_matrix=A,
                      dtype=dtype,
                      update_interval=update_interval,
                      eta=eta,
                      cutoff=cutoff,
                      save_dir=save_dir,
                      advance_mode=advance,
                      use_gpu=False)
    start_time = time.time()
    llock.forward()
    time_record[0] = time.time() - start_time
    time_record[1] = llock.times[3]
    time_record[2] = llock.times[3] / llock.times[4]
    print("LLOCK times : {}".format(time.time() - start_time))

    # record error infromation
    area_list = [xp.ones((Nf * Nf), dtype=bool), ~boundary]
    for r, area in enumerate(area_list):
        for t in range(Tf):
            mse_record[r, 0, t] = mean_squared_error(
                llock.get_filtered_value()[t][area], true_xp[t][area])
            mae_record[r, 0, t] = mean_absolute_error(
                llock.get_filtered_value()[t][area], true_xp[t][area])
            mse_record[r, 1, t] = mean_squared_error(filtered_value[t][area],
                                                     true_xp[t][area])
            mae_record[r, 1, t] = mean_absolute_error(filtered_value[t][area],
                                                      true_xp[t][area])
            mse_record[r, 2, t] = mean_squared_error(obs[t][area],
                                                     true_xp[t][area])
            mae_record[r, 2, t] = mean_absolute_error(obs[t][area],
                                                      true_xp[t][area])

    ## save error-record
    if True:
        xp.save(os.path.join(save_root, "time_record.npy"), time_record)
        xp.save(os.path.join(save_root, "mse_record.npy"), mse_record)
        xp.save(os.path.join(save_root, "mae_record.npy"), mae_record)

    # mse_record = np.load(os.path.join(save_root, "mse_record.npy"))

    fig, ax = plt.subplots(1, 1, figsize=(8, 5))
    for i, label in enumerate(["LLOCK", "KF", "observation"]):
        ax.plot(np.sqrt(mse_record[0, i]), label=label, lw=2)
    ax.set_xlabel("Timestep", fontsize=12)
    ax.set_ylabel("RMSE", fontsize=12)
    ax.legend(fontsize=15)
    fig.savefig(os.path.join(save_root, "rmse.png"), bbox_to_inches="tight")

    ## short-term prediction
    color_list = ["r", "g", "b"]
    threshold = 200
    pred_state = xp.zeros((Tf, Nf * Nf))
    pred_mse = mse_record[0].copy()

    s = threshold // update_interval
    F = np.load(os.path.join(save_dir,
                             "transition_matrix_{:02}.npy".format(s)))
    state = np.load(os.path.join(save_dir, "states.npy"))[threshold]
    pred_state[threshold] = state.reshape(-1)
    for t in range(threshold, Tf - 1):
        pred_state[t + 1] = F @ pred_state[t]

    kf_state = np.load(os.path.join(save_root, "kf_states.npy"))[threshold]
    for t in range(threshold, Tf):
        pred_mse[0, t] = mean_squared_error(pred_state[t], true_xp[t])
        pred_mse[1, t] = mean_squared_error(kf_state.reshape(-1), true_xp[t])
        pred_mse[2, t] = mean_squared_error(obs[threshold], true_xp[t])

    fig, ax = plt.subplots(1, 1, figsize=(8, 5))
    low = threshold - 4
    up = threshold + 6
    lw = 2
    for i, label in enumerate(["LLOCK", "KF", "observation"]):
        ax.plot(range(low, up),
                np.sqrt(pred_mse[i, low:up]),
                lw=lw,
                ls="--",
                c=color_list[i])
        ax.plot(range(low, threshold + 1),
                np.sqrt(mse_record[0, i, low:threshold + 1]),
                label=label,
                lw=lw,
                c=color_list[i])
    ax.set_xlabel("Timestep", fontsize=12)
    ax.set_ylabel("RMSE", fontsize=12)
    ax.legend(bbox_to_anchor=(1.05, 1.0), loc="upper left", fontsize=15)
    fig.savefig(os.path.join(save_root, "prediction.png"), bbox_inches="tight")

    ## substantial mse
    def translation_matrix4(W=10, H=10, direction=0, cyclic=False):
        xp = np
        F = xp.zeros((W * H, W * H))

        if direction == 0:  #right
            F_block = xp.diag(xp.ones(W - 1), -1)
            if cyclic:
                F_block[0, -1] = 1
            for i in range(H):
                F[i * W:(i + 1) * W, i * W:(i + 1) * W] = F_block

        elif direction == 1:  #left
            F_block = xp.diag(xp.ones(W - 1), 1)
            if cyclic:
                F_block[-1, 0] = 1
            for i in range(H):
                F[i * W:(i + 1) * W, i * W:(i + 1) * W] = F_block

        elif direction == 2:  #up
            F_block = xp.eye(W)
            for i in range(H - 1):
                F[i * W:(i + 1) * W, (i + 1) * W:(i + 2) * W] = F_block
            if cyclic:
                F[(H - 1) * W:H * W, 0:W] = F_block

        elif direction == 3:  # down
            F_block = xp.eye(W)
            for i in range(H - 1):
                F[(i + 1) * W:(i + 2) * W, i * W:(i + 1) * W] = F_block
            if cyclic:
                F[0:W, (H - 1) * W:H * W] = F_block
        return F

    change_interval = 250 // update_interval
    directions = [0, 2, 1, 3]

    mean_error = np.zeros((2, Tf // update_interval - 1))
    for t in range(Tf // update_interval - 1):
        fvalue = np.load(
            os.path.join(save_dir, "transition_matrix_{:02}.npy".format(t)))
        Ftrue = translation_matrix4(Nf, Nf, directions[t // change_interval],
                                    True)
        mean_error[0, t] = np.sqrt(
            np.power(
                np.absolute(fvalue - Ftrue)[A.astype(bool)
                                            & ~Ftrue.astype(bool)], 2).mean())
        mean_error[1, t] = np.sqrt(
            np.power(
                np.absolute(fvalue - Ftrue)[A.astype(bool)
                                            & Ftrue.astype(bool)], 2).mean())

    fig, ax = plt.subplots(1, 1, figsize=(8, 5))
    for i in range(2):
        ax.plot(update_interval * np.array(range(Tf // update_interval - 1)),
                mean_error[i],
                label="true={}".format(i),
                lw=lw)
    ax.set_xlabel("Timestep", fontsize=15)
    ax.set_ylabel("SRMSE", fontsize=15)
    # ax.set_yscale("log")
    ax.legend(fontsize=12)
    ax.tick_params(labelsize=12)
    fig.savefig(os.path.join(save_root, "srmse.png"), bbox_inches="tight")

    all_execute_time = int(time.time() - all_start_time)
    print("all time (sec): {} sec".format(all_execute_time))
    print("all time (min): {} min".format(int(all_execute_time // 60)))
    print("all time (hour): {} hour + {} min".format(
        int(all_execute_time // 3600), int((all_execute_time // 60) % 60)))