def check_tangent_matrix( conf, vec_x0, fun, fun_grad ): """Verify the correctness of the tangent matrix as computed by fun_grad() by comparing it with its finite difference approximation evaluated by repeatedly calling fun() with vec_x items perturbed by a small delta.""" vec_x = vec_x0.copy() delta = conf.delta vec_r = fun( vec_x ) # Update state. mtx_a0 = fun_grad( vec_x ) mtx_a = mtx_a0.tocsc() mtx_d = mtx_a.copy() mtx_d.data[:] = 0.0 vec_dx = nm.zeros_like( vec_r ) for ic in range( vec_dx.shape[0] ): vec_dx[ic] = delta xx = vec_x.copy() - vec_dx vec_r1 = fun( xx ) vec_dx[ic] = -delta xx = vec_x.copy() - vec_dx vec_r2 = fun( xx ) vec_dx[ic] = 0.0; vec = 0.5 * (vec_r2 - vec_r1) / delta ## ir = mtx_a.indices[mtx_a.indptr[ic]:mtx_a.indptr[ic+1]] ## for ii in ir: ## mtx_d[ii,ic] = vec[ii] ir = mtx_a.indices[mtx_a.indptr[ic]:mtx_a.indptr[ic+1]] mtx_d.data[mtx_a.indptr[ic]:mtx_a.indptr[ic+1]] = vec[ir] vec_r = fun( vec_x ) # Restore. tt = time.clock() print mtx_a, '.. analytical' print mtx_d, '.. difference' import sfepy.base.plotutils as plu plu.plot_matrix_diff( mtx_d, mtx_a, delta, ['difference', 'analytical'], conf.check ) return time.clock() - tt
def check_tangent_matrix( conf, vec_x0, mtx_a0, evaluator ): vec_x = vec_x0.copy() delta = conf.delta vec_r, status = evaluator.eval_residual( vec_x ) # Update state. mtx_a0, status = evaluator.eval_tangent_matrix( vec_x, mtx_a0 ) mtx_a = mtx_a0.tocsc() mtx_d = mtx_a.copy() mtx_d.data[:] = 0.0 vec_dx = nm.zeros_like( vec_r ) for ic in range( vec_dx.shape[0] ): vec_dx[ic] = delta xx = vec_x.copy() evaluator.update_vec( xx, vec_dx ) vec_r1, status = evaluator.eval_residual( xx ) vec_dx[ic] = -delta xx = vec_x.copy() evaluator.update_vec( xx, vec_dx ) vec_r2, status = evaluator.eval_residual( xx ) vec_dx[ic] = 0.0; vec = 0.5 * (vec_r2 - vec_r1) / delta ## ir = mtx_a.indices[mtx_a.indptr[ic]:mtx_a.indptr[ic+1]] ## for ii in ir: ## mtx_d[ii,ic] = vec[ii] ir = mtx_a.indices[mtx_a.indptr[ic]:mtx_a.indptr[ic+1]] mtx_d.data[mtx_a.indptr[ic]:mtx_a.indptr[ic+1]] = vec[ir] vec_r, status = evaluator.eval_residual( vec_x ) # Restore. tt = time.clock() print mtx_a, '.. analytical' print mtx_d, '.. difference' plu.plot_matrix_diff( mtx_d, mtx_a, delta, ['difference', 'analytical'], conf.check ) return time.clock() - tt