def solve_qr_colamd(A, b): # TODO: return x, R s.t. Ax = b, and |Ax - b|^2 = |R E^T x - d|^2 + |e|^2, with reordered QR decomposition (E is the permutation matrix). # https://github.com/theNded/PySPQR z, R, E, rank = rz(A, b, permc_spec='COLAMD') x = permutation_vector_to_matrix(E) @ spsolve_triangular(R, z, lower=False) return x, R
def solve_qr(A, b): # TODO: return x, R s.t. Ax = b, and |Ax - b|^2 = |Rx - d|^2 + |e|^2 # https://github.com/theNded/PySPQR z, R, E, rank = rz(A, b, permc_spec='NATURAL') z = z.flatten() x = spsolve_triangular(csr_matrix(R), z, lower=False) return x, R
def solve_qr_colamd(A, b): # TODO: return x, R s.t. Ax = b, and |Ax - b|^2 = |R E^T x - d|^2 + |e|^2, with reordered QR decomposition (E is the permutation matrix). # https://github.com/theNded/PySPQR N = A.shape[1] x = np.zeros((N, )) z, R, E, rank = rz(A, b, permc_spec='COLAMD') z = z.flatten() x_prime = spsolve_triangular(csr_matrix(R), z, lower=False) x[E] = x_prime return x, R
def solve_qr(A, b): # TODO: return x, R s.t. Ax = b, and |Ax - b|^2 = |Rx - d|^2 + |e|^2 # https://github.com/theNded/PySPQR N = A.shape[1] x = np.zeros((N, )) R = eye(N) Z, R, E, rank = rz(A, b, permc_spec='NATURAL') # print(rank) x = spsolve_triangular(csr_matrix(R), Z, lower=False) return x, R
def solve_qr_colamd(A, b): # TODO: return x, R s.t. Ax = b, and |Ax - b|^2 = |R E^T x - d|^2 + |e|^2, # with reordered QR decomposition (E is the permutation matrix). # https://github.com/theNded/PySPQR N = A.shape[1] x = np.zeros((N, )) R = eye(N) Z, R, E, rank = rz(A, b, permc_spec='COLAMD') # print(rank) R = R.tocsr() Z = Z.flatten() x = permutation_vector_to_matrix(E) @ spsolve_triangular(R, Z, lower=False) # x = spsolve_triangular(csr_matrix(R@permutation_vector_to_matrix(E).T),Z,lower=False) return x, R
def parse_errors(E, Gcoo, TCinv, rhs, Ip_c, Ip_r, grids, G_data, Gc, G_dzbar, bias_model, bias_params, dzdt_lags=None, timing={}): tic=time() # take the QZ transform of Gcoo # TEST WHETHER rhs can just be a vector of ones z, R, perm, rank=sparseqr.rz(Ip_r.dot(TCinv.dot(Gcoo)), Ip_r.dot(TCinv.dot(rhs))) z=z.ravel() R=R.tocsr() R.sort_indices() R.eliminate_zeros() timing['decompose_qz']=time()-tic E0=np.zeros(R.shape[0]) # compute Rinv for use in propagating errors. # what should the tolerance be? We will eventually square Rinv and take its # row-wise sum. We care about errors at the cm level, so # size(Rinv)*tol^2 = 0.01 -> tol=sqrt(0.01/size(Rinv))~ 1E-4 tic=time(); RR, CC, VV, status=inv_tr_upper(R, np.int(np.prod(R.shape)/4), 1.e-5); # save Rinv as a sparse array. The syntax perm[RR] undoes the permutation from QZ Rinv=sp.coo_matrix((VV, (perm[RR], CC)), shape=R.shape).tocsr(); timing['Rinv_cython']=time()-tic; tic=time(); E0=np.sqrt(Rinv.power(2).sum(axis=1)); timing['propagate_errors']=time()-tic; # generate the full E vector. E0 appears to be an ndarray, E0=np.array(Ip_c.dot(E0)).ravel() E['z0']=np.reshape(E0[Gc.TOC['cols']['z0']], grids['z0'].shape) E['dz']=np.reshape(E0[Gc.TOC['cols']['dz']], grids['dz'].shape) # generate the lagged dz errors: for lag in dzdt_lags: this_name='dzdt_lag%d' % lag E[this_name]=lin_op(grids['dz'], name=this_name, col_N=G_data.col_N).dzdt(lag=lag).grid_error(Ip_c.dot(Rinv)) # note: this should probably be dotted with the G_dzbar op. lag op is nlag*nt, G_dzbar is nt*ncols, R is NcolsxNcols RUN ONE LINE AT A TIME this_name='dzdt_bar_lag%d' % lag this_op=lin_op(grids['t'], name=this_name).diff(lag=lag).toCSR().dot(G_dzbar) E[this_name]=np.sqrt((this_op.dot(Ip_c).dot(Rinv)).power(2).sum(axis=1)) # generate the grid-mean error for zero lag E['dz_bar']=np.sqrt((G_dzbar.dot(Ip_c).dot(Rinv)).power(2).sum(axis=1)) E['bias'], E['slope_bias']=parse_biases(E0, bias_model, bias_params)
def calc_and_parse_errors(E, Gcoo, TCinv, rhs, Ip_c, Ip_r, grids, G_data, Gc, avg_ops, bias_model, bias_params, dzdt_lags=None, timing={}, error_scale=1): tic = time() # take the QZ transform of Gcoo # TEST WHETHER rhs can just be a vector of ones z, R, perm, rank = sparseqr.rz(Ip_r.dot(TCinv.dot(Gcoo)), Ip_r.dot(TCinv.dot(rhs))) z = z.ravel() R = R.tocsr() R.sort_indices() R.eliminate_zeros() timing['decompose_qz'] = time() - tic E0 = np.zeros(R.shape[0]) # compute Rinv for use in propagating errors. # what should the tolerance be? We will eventually square Rinv and take its # row-wise sum. We care about errors at the cm level, so # size(Rinv)*tol^2 = 0.01 -> tol=sqrt(0.01/size(Rinv))~ 1E-4 tic = time() RR, CC, VV, status = inv_tr_upper(R, np.int(np.prod(R.shape) / 4), 1.e-5) # save Rinv as a sparse array. The syntax perm[RR] undoes the permutation from QZ Rinv = sp.coo_matrix((VV, (perm[RR], CC)), shape=R.shape).tocsr() timing['Rinv_cython'] = time() - tic tic = time() E0 = np.sqrt(Rinv.power(2).sum(axis=1)) timing['propagate_errors'] = time() - tic # if a scaling for the errors has been provided, mutliply E0 by it E0 *= error_scale # generate the full E vector. E0 appears to be an ndarray, E0 = np.array(Ip_c.dot(E0)).ravel() E['sigma_z0']=pc.grid.data().from_dict({'x':grids['z0'].ctrs[1],\ 'y':grids['z0'].ctrs[0],\ 'sigma_z0':np.reshape(E0[Gc.TOC['cols']['z0']], grids['z0'].shape)}) E['sigma_dz']=pc.grid.data().from_dict({'x':grids['dz'].ctrs[1],\ 'y':grids['dz'].ctrs[0],\ 'time':grids['dz'].ctrs[2],\ 'sigma_dz': np.reshape(E0[Gc.TOC['cols']['dz']], grids['dz'].shape)}) # generate the lagged dz errors: [CHECK THIS] for key, op in avg_ops.items(): E['sigma_'+key] = pc.grid.data().from_dict({'x':op.dst_grid.ctrs[1], \ 'y':op.dst_grid.ctrs[0], \ 'time': op.dst_grid.ctrs[2], \ 'sigma_'+key: op.grid_error(Ip_c.dot(Rinv))}) # generate the grid-mean error for zero lag if len(bias_model.keys()) > 0: E['sigma_bias'], E['sigma_slope_bias'] = parse_biases( E0, bias_model, bias_params)