Skip to content

Commit b36cc9f

Browse files
committed
Revert "added calc_utils"
This reverts commit 1428e4c, reversing changes made to 094a269.
1 parent 1428e4c commit b36cc9f

20 files changed

+329
-3938
lines changed

pymc/CommonDeterministics.py

Lines changed: 41 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,11 @@
1515
from Container import Container
1616
from InstantiationDecorators import deterministic, check_special_methods
1717
import numpy as np
18-
from numpy import sum, shape,size, ravel, sign, zeros, ones, broadcast, newaxis
19-
import inspect, types
20-
from utils import safe_len, stukel_logit, stukel_invlogit, logit, invlogit, value, find_element
18+
import inspect
19+
from utils import safe_len, stukel_logit, stukel_invlogit, logit, invlogit, value
2120
from types import UnboundMethodType
2221
from copy import copy
2322
import sys
24-
import operator, __builtin__
2523

2624
__all__ = ['CompletedDirichlet', 'LinearCombination', 'Index', 'Lambda', 'lambda_deterministic', 'lam_dtrm',
2725
'logit', 'invlogit', 'stukel_logit', 'stukel_invlogit', 'Logit', 'InvLogit', 'StukelLogit', 'StukelInvLogit',
@@ -319,7 +317,7 @@ def eval_fun(x, y):
319317
stochastic_elem = x[i]
320318
self.sides[stochastic_elem].append('L')
321319
this_coef = Lambda('%s_coef'%stochastic_elem, lambda c=y[i]: np.asarray(c))
322-
self.coefs[stochastic_elem].append(this_coef)
320+
self.coefs[stochastic_elem].append(this_coef)
323321

324322
if isinstance(y[i], pm.Stochastic):
325323

@@ -486,36 +484,25 @@ def wrapper(**wkwds_in):
486484
# = Add special methods to variables to support FBC syntax =
487485
# ==========================================================
488486

489-
def create_uni_method(op_name, klass, jacobians = None):
487+
def create_uni_method(op_name, klass):
490488
"""
491489
Creates a new univariate special method, such as A.__neg__() <=> -A,
492490
for target class. The method is called __op_name__.
493491
"""
494492
# This function will become the actual method.
495-
op_modules = [operator, __builtin__]
496-
op_names = [ op_name, op_name + '_']
497-
498-
op_function_base = find_element( op_names,op_modules, error_on_fail = True)
499-
#many such functions do not take keyword arguments, so we need to wrap them
500-
def op_function(self):
501-
return op_function_base(self)
502-
503493
def new_method(self):
504494
# This code creates a Deterministic object.
505-
if not check_special_methods():
506-
raise NotImplementedError, 'Special method %s called on %s, but special methods have been disabled. Set pymc.special_methods_available to True to enable them.'%(op_name, str(self))
507-
508-
jacobian_formats = {'self' : 'transformation_operation'}
509-
return pm.Deterministic(op_function,
495+
def eval_fun(self,op=op):
496+
if not check_special_methods():
497+
raise NotImplementedError, 'Special method %s called on %s, but special methods have been disabled. Set pymc.special_methods_available to True to enable them.'%(op_name, str(self))
498+
return getattr(self, op)()
499+
return pm.Deterministic(eval_fun,
510500
'A Deterministic returning the value of %s(%s)'%(op_name, self.__name__),
511501
'('+op_name+'_'+self.__name__+')',
512-
parents = {'self':self},
502+
{'self':self, 'op': '__'+op_name+'__'},
513503
trace=False,
514-
plot=False,
515-
jacobians=jacobians,
516-
jacobian_formats = jacobian_formats)
517-
# Make the function into a method for klass.
518-
504+
plot=False)
505+
# Make the function into a method for klass.
519506
new_method.__name__ = '__'+op_name+'__'
520507
setattr(klass, new_method.__name__, UnboundMethodType(new_method, None, klass))
521508

@@ -533,11 +520,7 @@ def new_method(self, op=op):
533520
new_method.__name__ = '__'+op.__name__+'__'
534521
setattr(klass, new_method.__name__, UnboundMethodType(new_method, None, klass))
535522

536-
537-
538-
539-
540-
def create_rl_bin_method(op_name, klass, jacobians = {}):
523+
def create_rl_bin_method(op_name, klass):
541524
"""
542525
Creates a new binary special method with left and right versions, such as
543526
A.__mul__(B) <=> A*B,
@@ -547,33 +530,34 @@ def create_rl_bin_method(op_name, klass, jacobians = {}):
547530
# Make left and right versions.
548531
for prefix in ['r','']:
549532
# This function will became the methods.
550-
op_modules = [operator, __builtin__]
551-
op_names = [ op_name, op_name + '_']
552-
553-
op_function_base = find_element( op_names, op_modules, error_on_fail = True)
554-
#many such functions do not take keyword arguments, so we need to wrap them
555-
def op_function(a, b):
556-
return op_function_base(a, b)
557-
558533
def new_method(self, other, prefix=prefix):
559534
if not check_special_methods():
560535
raise NotImplementedError, 'Special method %s called on %s, but special methods have been disabled. Set pymc.special_methods_available to True to enable them.'%(op_name, str(self))
561536
# This code will create one of two Deterministic objects.
562537
if prefix == 'r':
563-
parents = {'a':other, 'b':self}
564-
538+
# Right version: raises error on failure.
539+
parents = {'self':self, 'other':other, 'op':'__r' + op_name + '__'}
540+
def eval_fun(self,other,op):
541+
out = getattr(self, op)(other)
542+
if out is NotImplemented:
543+
# the rt version has failed, meainng the lft version has failed as well.
544+
raise TypeError, "unsupported operand type(s) for %s: '%s' and '%s'"%(op.replace('_',''), self.__class__.__name__, other.__class__.__name__)
545+
return out
565546
else:
566-
parents = {'a':self, 'b':other}
567-
jacobian_formats = {'a' : 'broadcast_operation',
568-
'b' : 'broadcast_operation'}
569-
return pm.Deterministic(op_function,
547+
# Left version: tries right version on failure.
548+
parents = {'self':self, 'other':other, 'op':'__' + op_name + '__', 'rt_op': '__r'+op_name+'__'}
549+
def eval_fun(self, other, op, rt_op):
550+
out = getattr(self, op)(other)
551+
if out is NotImplemented:
552+
# if try the rt version.
553+
out = getattr(other, rt_op)(self)
554+
return out
555+
return pm.Deterministic(eval_fun,
570556
'A Deterministic returning the value of %s(%s,%s)'%(prefix+op_name,self.__name__, str(other)),
571557
'('+'_'.join([self.__name__,prefix+op_name,str(other)])+')',
572558
parents,
573559
trace=False,
574-
plot=False,
575-
jacobians = jacobians,
576-
jacobian_formats = jacobian_formats)
560+
plot=False)
577561
# Convert the functions into methods for klass.
578562
new_method.__name__ = '__'+prefix+op_name+'__'
579563
setattr(klass, new_method.__name__, UnboundMethodType(new_method, None, klass))
@@ -644,62 +628,20 @@ def new_method(self, *args):
644628
new_method.__name__ = '__'+op_name+'__'
645629
setattr(klass, new_method.__name__, UnboundMethodType(new_method, None, klass))
646630

647-
def op_to_jacobians(op, module):
648-
if type(module) is types.ModuleType:
649-
module = copy(module.__dict__)
650-
elif type(module) is dict:
651-
module = copy(module)
652-
else:
653-
raise AttributeError
654-
655-
name = op + "_jacobians"
656-
try:
657-
jacobians = module[name]
658-
except:
659-
jacobians = {}
660-
661-
return jacobians
662-
663631
# Left/right binary operators
664-
665-
666-
truediv_jacobians = {'a' : lambda a, b: ones(shape(a))/b,
667-
'b' : lambda a, b: - a / b**2 }
668-
669-
div_jacobians = truediv_jacobians
670-
671-
pow_jacobians = {'a' : lambda a, b: b * a**(b - 1.0),
672-
'b' : lambda a, b: np.log(a) * a**b}
673-
674-
675632
for op in ['div', 'truediv', 'floordiv', 'mod', 'divmod', 'pow', 'lshift', 'rshift', 'and', 'xor', 'or']:
676-
create_rl_bin_method(op, Variable, jacobians = op_to_jacobians(op, locals()))
677-
678-
# Binary operators eq not part of this set because it messes up having stochastics in lists
679-
for op in ['lt', 'le', 'ne', 'gt', 'ge']:
680-
create_bin_method(op ,Variable)
681-
682-
def equal(s1, s2): #makes up for deficiency of __eq__
683-
return pm.Deterministic(lambda x1, x2 : x1 == x2,
684-
'A Deterministic returning the value of x1 == x2',
685-
'('+'_'.join([s1.__name__,'=',str(s2)])+')',
686-
{'x1':s1, 'x2':s2},
687-
trace=False,
688-
plot=False)
633+
create_rl_bin_method(op, Variable)
689634

635+
# # Binary operators
636+
# for op in ['lt', 'le', 'eq', 'ne', 'gt', 'ge']:
637+
# create_bin_method(op ,Variable)
690638

691639
# Unary operators
692-
neg_jacobians = {'self' : lambda self: -ones(shape(self))}
693-
694-
pos_jacobians = {'self' : lambda self: np.ones(shape(self))}
695-
696-
abs_jacobians = {'self' : lambda self: np.sign(self)}
697-
698-
for op in ['neg','abs','invert']: # no need for pos and __index__ seems to cause a lot of problems
699-
create_uni_method(op, Variable, jacobians = op_to_jacobians(op, locals()))
640+
for op in ['neg','pos','abs','invert','index']:
641+
create_uni_method(op, Variable)
700642

701643
# Casting operators
702-
for op in [iter,complex,int,long,float,oct,hex]:
644+
for op in [iter,complex,int,long,float,oct,hex,len]:
703645
create_casting_method(op, Variable)
704646

705647
# Addition, subtraction, multiplication
@@ -712,50 +654,31 @@ def equal(s1, s2): #makes up for deficiency of __eq__
712654
# create_rl_lin_comb_method('rmul', Variable, ['self'],['other'])
713655

714656
#TODO: Comment once LinearCombination issues are ironed out.
715-
716-
add_jacobians = {'a' : lambda a, b: ones(broadcast(a,b).shape),
717-
'b' : lambda a, b: ones(broadcast(a,b).shape)}
718-
719-
mul_jacobians = {'a' : lambda a, b: ones(shape(a)) * b,
720-
'b' : lambda a, b: ones(shape(b)) * a}
721-
722-
sub_jacobians = {'a' : lambda a, b: ones(broadcast(a,b).shape),
723-
'b' : lambda a, b: -ones(broadcast(a,b).shape)}
724-
725657
for op in ['add', 'mul', 'sub']:
726-
create_rl_bin_method(op, Variable, jacobians = op_to_jacobians(op, locals()))
658+
create_rl_bin_method(op, Variable)
727659

728660
for op in ['iadd','isub','imul','idiv','itruediv','ifloordiv','imod','ipow','ilshift','irshift','iand','ixor','ior','unicode']:
729661
create_nonimplemented_method(op, Variable)
730662

731663

732-
def getitem_jacobian(self, index):
733-
return index
734-
735-
736664
# Create __getitem__ method.
737665
def __getitem__(self, index):
738666
if not check_special_methods():
739667
raise NotImplementedError, 'Special method __index__ called on %s, but special methods have been disabled. Set pymc.special_methods_available to True to enable them.'%str(self)
740668
# If index is number or number-valued variable, make an Index object
741669
name = '%s[%s]'%(self.__name__, str(index))
742-
if np.isscalar(value(index)) and len(np.shape(self.value)) < 2:
670+
if np.isscalar(value(index)):
743671
if np.isreal(value(index)):
744672
return Index(name, self, index, trace=False, plot=False)
745673
# Otherwise make a standard Deterministic.
746674
def eval_fun(self, index):
747675
return self[index]
748-
749-
jacobians = {'self' : getitem_jacobian}
750-
jacobian_formats = {'self' : 'index_operation'}
751676
return pm.Deterministic(eval_fun,
752677
'A Deterministic returning the value of %s[%s]'%(self.__name__, str(index)),
753678
name,
754679
{'self':self, 'index':index},
755680
trace=False,
756-
plot=False,
757-
jacobians = jacobians,
758-
jacobian_formats = jacobian_formats)
681+
plot=False)
759682
Variable.__getitem__ = UnboundMethodType(__getitem__, None, Variable)
760683

761684
# Create __call__ method for Variable.

pymc/Node.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,28 +28,7 @@ def logp_of_set(s):
2828
else:
2929
raise exc[0], exc[1], exc[2]
3030

31-
def logp_gradient_of_set(variable_set, calculation_set = None):
32-
"""
33-
Calculates the gradient of the joint log posterior with respect to all the variables in variable_set.
34-
Calculation of the log posterior is restricted to the variables in calculation_set.
35-
36-
Returns a dictionary of the gradients.
37-
"""
38-
39-
logp_gradients = {}
40-
for variable in variable_set:
41-
logp_gradients[variable] = logp_gradient(variable, calculation_set)
42-
43-
return logp_gradients
44-
45-
def logp_gradient(variable, calculation_set = None):
46-
"""
47-
Calculates the gradient of the joint log posterior with respect to variable.
48-
Calculation of the log posterior is restricted to the variables in calculation_set.
49-
"""
50-
return variable.logp_partial_gradient(variable, calculation_set) + sum([child.logp_partial_gradient(variable, calculation_set) for child in variable.children] )
5131

52-
5332
def batchsd(trace, batches=5):
5433
"""
5534
Calculates the simulation standard error, accounting for non-independent

0 commit comments

Comments
 (0)