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