def mlogit_warp_grad(alpha, nu, q, y, max_itr=8000, tol=1e-4, deltaO=0.008, deltag=0.008, display=0): """ calculates optimal warping for functional multinomial logistic regression :param alpha: scalar :param nu: numpy ndarray of shape (M,N) of M functions with N samples :param q: numpy ndarray of shape (M,N) of M functions with N samples :param y: numpy ndarray of shape (1,N) of M functions with N samples responses :param max_itr: maximum number of iterations (Default=8000) :param tol: stopping tolerance (Default=1e-10) :param deltaO: gradient step size for rotation (Default=0.008) :param deltag: gradient step size for warping (Default=0.008) :param display: display iterations (Default=0) :rtype: tuple of numpy array :return gam_old: warping function """ alpha = alpha/norm(alpha) q, scale = cf.scale_curve(q) # q/norm(q) for ii in range(0, nu.shape[2]): nu[:, :, ii], scale = cf.scale_curve(nu[:, :, ii]) # nu/norm(nu) gam_old, O_old = mw.ocmlogit_warp(np.ascontiguousarray(alpha), np.ascontiguousarray(nu), np.ascontiguousarray(q), np.ascontiguousarray(y, dtype=np.int32), max_itr, tol, deltaO, deltag, display) return (gam_old, O_old)
def preproc_open_curve(beta, T=100): n, M, k = beta.shape q = np.zeros((n, T, k)) beta2 = np.zeros((n, T, k)) for i in range(0, k): beta1 = beta[:, :, i] beta1, scale = cf.scale_curve(beta1) beta1 = cf.resamplecurve(beta1, T) centroid1 = cf.calculatecentroid(beta1) beta1 = beta1 - np.tile(centroid1, [T, 1]).T beta2[:, :, i] = beta1 q[:, :, i] = cf.curve_to_q(beta1) return (q, beta2)
def curve_principal_directions(betamean, mu, K, mode='O', no=3, N=5): """ Computes principal direction of variation specified by no. N is Number of shapes away from mean. Creates 2*N+1 shape sequence :param betamean: numpy ndarray of shape (n, M) describing the mean curve :param mu: numpy ndarray of shape (n, M) describing the mean srvf :param K: numpy ndarray of shape (M, M) describing the covariance :param mode: Open ('O') or closed curve ('C') (default 'O') :param no: number of direction (default 3) :param N: number of shapes (2*N+1) (default 5) :rtype: tuple of numpy array :return pd: principal directions """ n, T = betamean.shape modes = ['O', 'C'] mode = [i for i, x in enumerate(modes) if x == mode] if len(mode) == 0: mode = 0 else: mode = mode[0] U, s, V = svd(K) qarray = empty((no, 2*N+1), dtype=object) qarray1 = empty(N, dtype=object) qarray2 = empty(N, dtype=object) pd = empty((no, 2*N+1), dtype=object) pd1 = empty(N, dtype=object) pd2 = empty(N, dtype=object) for m in range(0, no): princDir = vstack((U[0:T, m], U[T:2*T, m])) v = sqrt(s[m]) * princDir q1 = mu epsilon = 2./N # Forward direction from mean for i in range(0, N): normv = sqrt(cf.innerprod_q2(v, v)) if normv < 1e-4: q2 = mu else: q2 = cos(epsilon*normv)*q1 + sin(epsilon*normv)*v/normv if mode == 1: q2 = cf.project_curve(q2) qarray1[i] = q2 p = cf.q_to_curve(q2) centroid1 = -1*cf.calculatecentroid(p) beta_scaled, scale = cf.scale_curve(p + tile(centroid1, [T, 1]).T) pd1[i] = beta_scaled # Parallel translate tangent vector basis2 = cf.find_basis_normal(q2) v = cf.parallel_translate(v, q1, q2, basis2, mode) q1 = q2 # Backward direction from mean v = -sqrt(s[m])*princDir q1 = mu for i in range(0, N): normv = sqrt(cf.innerprod_q2(v, v)) if normv < 1e-4: q2 = mu else: q2 = cos(epsilon*normv)*q1+sin(epsilon*normv)*v/normv if mode == 1: q2 = cf.project_curve(q2) qarray2[i] = q2 p = cf.q_to_curve(q2) centroid1 = -1*cf.calculatecentroid(p) beta_scaled, scale = cf.scale_curve(p + tile(centroid1, [T, 1]).T) pd2[i] = beta_scaled # Parallel translate tangent vector basis2 = cf.find_basis_normal(q2) v = cf.parallel_translate(v, q1, q2, basis2, mode) q1 = q2 for i in range(0, N): qarray[m, i] = qarray2[(N-1)-i] pd[m, i] = pd2[(N-1)-i] qarray[m, N] = mu centroid1 = -1*cf.calculatecentroid(betamean) beta_scaled, scale = cf.scale_curve(betamean + tile(centroid1, [T, 1]).T) pd[m, N] = beta_scaled for i in range(N+1, 2*N+1): qarray[m, i] = qarray1[i-(N+1)] pd[m, i] = pd1[i-(N+1)] return(pd)