def PerformIca(X,Y,num_components,random_state):
    result = {}
    algo = FastICA(random_state=random_state,max_iter=800)
    algo.fit(X)
    full_mixing_matrix = algo.mixing_
    full_unmixing_matrix = algo.components_
    _x = algo.transform(X)
    kt_value = np.abs(kt(_x))
    largest_kt_values_idx = np.argsort(kt_value)[::-1]
    result["ica_kt_all"] = kt_value

    for n in num_components:
        prefix = "ica_" + str(n) + "_"
        component_idx_to_select = largest_kt_values_idx[0:n]
        mixing_matrix = full_mixing_matrix.T[component_idx_to_select,:].T
        unmixing_matrix = full_unmixing_matrix[component_idx_to_select,:]
        algo.components_ = unmixing_matrix
        algo.mixing_ = mixing_matrix

        result[prefix+"mm"] = mixing_matrix
        result[prefix+"umm"] = unmixing_matrix

        _x = algo.transform(X)
        result[prefix+"data"] = _x
        X_recons = algo.inverse_transform(_x)
        result[prefix+"reconstruction_error"] = ComputeReconstructionSSE(X,X_recons)
        n_kt_value = kt_value[component_idx_to_select]
        avg_kt = n_kt_value.mean()
        #print("ICA num dim {0} : reconstruction error {1} avg kt {2}".format(str(n),str(result[prefix+"reconstruction_error"]),str(avg_kt)))
        #print(np.sort(n_kt_value))
    return result