def test_BlockMatrix_Inverse_execution(): k, n = 2, 4 dtype = 'float32' A = sympy.MatrixSymbol('A', n, k) B = sympy.MatrixSymbol('B', n, n) inputs = A, B output = B.I*A cutsizes = {A: [(n/2, n/2), (k/2, k/2)], B: [(n/2, n/2), (n/2, n/2)]} cutinputs = [sympy.blockcut(i, *cutsizes[i]) for i in inputs] cutoutput = output.subs(dict(zip(inputs, cutinputs))) dtypes = dict(zip(inputs, [dtype]*len(inputs))) f = theano_function(inputs, [output], dtypes=dtypes) fblocked = theano_function(inputs, [sympy.block_collapse(cutoutput)], dtypes=dtypes) import numpy ninputs = [numpy.random.rand(*x.shape).astype(dtype) for x in inputs] ninputs = [numpy.arange(n*k).reshape(A.shape).astype(dtype), numpy.eye(n).astype(dtype)] ninputs[1] += numpy.ones(B.shape)*1e-5 assert numpy.allclose(f(*ninputs), fblocked(*ninputs), rtol=1e-5)
def obs_term_gradient_optimization2(background_data_vector, observation_data_vector, actual_B_1, actual_R_1, actual_H, actual_hx, smallest_gradient=0.01, iteration_step=0.001, blockn=5, enable_parallel=False): """http://matthewrocklin.com/blog/work/2013/04/05/SymPy-Theano-part-3""" len_background_data_vector = len(background_data_vector) len_observation_data_vector = len(background_data_vector) # background_error_matrix_reverse = sympy.MatrixSymbol('B_1', len(background_data_vector), len(background_data_vector)) background_error_matrix_reverse = sympy.MatrixSymbol( 'B_1', len_background_data_vector, len_background_data_vector) observation_error_matrix_reverse = sympy.MatrixSymbol( 'R_1', len_observation_data_vector, len_observation_data_vector) linearized_observation_operator = sympy.MatrixSymbol( 'H', len_observation_data_vector, len_background_data_vector) background_derived_obs_matrix = sympy.MatrixSymbol( 'hx', len_observation_data_vector, 1) observation_data_matrix = sympy.MatrixSymbol('y', len_observation_data_vector, 1) analysis_increment_vector_symbol = sympy.MatrixSymbol( 'delta_x', len_background_data_vector, 1) obs_term_gradient_value = numpy.matrix( 999.0 * numpy.ones(background_data_vector.shape)) analysis_increment_vector = numpy.matrix( numpy.zeros(background_data_vector.shape)) inputs = [ background_error_matrix_reverse, observation_error_matrix_reverse, linearized_observation_operator, background_derived_obs_matrix, observation_data_matrix, analysis_increment_vector_symbol ] cost_function_gradient = [ 2 * background_error_matrix_reverse * analysis_increment_vector_symbol - 2 * linearized_observation_operator.transpose() * observation_error_matrix_reverse * (observation_data_matrix - background_derived_obs_matrix - linearized_observation_operator * analysis_increment_vector_symbol) ] dtypes = {inp: 'float16' for inp in inputs} print 'create func' if enable_parallel: blocksizes = { background_error_matrix_reverse: [ tuple(blockn * [len_background_data_vector / blockn]), tuple(blockn * [len_background_data_vector / blockn]) ], observation_error_matrix_reverse: [ tuple(blockn * [len_observation_data_vector / blockn]), tuple(blockn * [len_observation_data_vector / blockn]) ], linearized_observation_operator: [ tuple(blockn * [len_observation_data_vector / blockn]), tuple(blockn * [len_background_data_vector / blockn]) ], background_derived_obs_matrix: [tuple(blockn * [len_observation_data_vector / blockn]), (1, )], observation_data_matrix: [tuple(blockn * [len_observation_data_vector / blockn]), (1, )], analysis_increment_vector_symbol: [tuple(blockn * [len_background_data_vector / blockn]), (1, )], } blockinputs = [blockcut(i, *blocksizes[i]) for i in inputs] blockoutputs = [ o.subs(dict(zip(inputs, blockinputs))) for o in cost_function_gradient ] collapsed_outputs = map(block_collapse, blockoutputs) f = theano_function(inputs, collapsed_outputs, dtypes=dtypes) else: f = theano_function(inputs, cost_function_gradient, dtypes=dtypes) #f=sympy.lambdify(analysis_increment_vector_symbol, obs_gradient, 'numpy') #f=sympy.lambdify(analysis_increment_vector_symbol, obs_gradient, 'sympy') print 'created func' n = 0 while (obs_term_gradient_value.sum() <= -smallest_gradient or obs_term_gradient_value.sum() > smallest_gradient): ninputs = [ numpy.array(actual_B_1).astype(float16), numpy.array(actual_R_1).astype(float16), numpy.array(actual_H).astype(float16), numpy.array(actual_hx).astype(float16), numpy.array(observation_data_vector).astype(float16), numpy.array(analysis_increment_vector).astype(float16) ] # [2*B_1*delta_x - 2*H.T*R_1*(-hx - H*delta_x + y)] # obs_term_gradient_value = 2*actual_B_1*analysis_increment_vector - 2*actual_H.transpose()*actual_R_1*(observation_data_vector-actual_hx-actual_H*analysis_increment_vector) #obs_term_gradient_value = 2*numpy.asarray(actual_B_1)*numpy.asarray(analysis_increment_vector) - 2*actual_H.transpose()*actual_R_1*(observation_data_vector-actual_hx-actual_H*analysis_increment_vector) obs_term_gradient_value = f(*ninputs) analysis_increment_vector = analysis_increment_vector - iteration_step * obs_term_gradient_value print n, obs_term_gradient_value.sum() n = n + 1 if n > 2000: break # print analysis_increment_vector # print background_data_vector + analysis_increment_vector return background_data_vector + analysis_increment_vector
from kalman import inputs, outputs, Sigma, H, R, mu, data, n, k from sympy import blockcut, block_collapse blocksizes = { Sigma: [(n / 2, n / 2), (n / 2, n / 2)], H: [(k / 2, k / 2), (n / 2, n / 2)], R: [(k / 2, k / 2), (k / 2, k / 2)], mu: [(n / 2, n / 2), (1, )], data: [(k / 2, k / 2), (1, )] } blockinputs = [blockcut(i, *blocksizes[i]) for i in inputs] blockoutputs = [o.subs(dict(zip(inputs, blockinputs))) for o in outputs] collapsed_outputs = map(block_collapse, blockoutputs) from sympy.printing.theanocode import theano_function dtype = 'float64' dtypes = dict(zip(inputs, [dtype] * len(inputs))) f = theano_function(inputs, outputs, dtypes=dtypes) fblocked = theano_function(inputs, collapsed_outputs, dtypes=dtypes) import numpy ninputs = [numpy.random.rand(*i.shape).astype(dtype) for i in inputs]