Implemented crisscross algorithm for solving LP problems.
[sympycore.git] / sympycore / utils.py
blobd9ce8b82d8cc6787ae5649747d6de893b9ecd230
1 """Provides various implementation specific constants (expression heads, etc).
2 """
4 __docformat__ = 'restructuredtext'
6 import inspect
8 class HEAD(object):
9 """ Base class to head constants.
11 Head constants are singletons.
12 """
13 _cache = {}
14 def __new__(cls, *args):
15 key = '%s%s' % (cls.__name__, args)
16 obj = cls._cache.get(key)
17 if obj is None:
18 obj = object.__new__(cls)
19 cls._cache[key] = obj
20 obj._key = key
21 obj.init(*args)
22 return obj
24 def init(self, *args):
25 # derived class may set attributes here
26 pass #pragma NO COVER
28 def as_unique_head(self):
29 # used by the pickler support to make HEAD instances unique
30 try:
31 return self._cache[self._key]
32 except KeyError:
33 self._cache[self._key] = self
34 return self
36 def is_data_ok(self, cls, expr):
37 return
39 # The following constants define both the order of operands
40 # as well as placing parenthesis for classes deriving from
41 # CollectingField:
43 str_SUM = -1
44 str_PRODUCT = -2
45 str_POWER = -3
46 str_APPLY = -4
47 str_SYMBOL = -5
48 str_NUMBER = -6
50 # The following constants are used by Verbatim and
51 # CollectingField classes.
55 #POLY = HEAD('POLY')
56 #DENSE_POLY = HEAD('DENSE_POLY')
58 DIFF = HEAD('DIFF')
60 MATRIX_DICT = intern('MATRIX_DICT')
61 MATRIX_DICT_T = intern('MATRIX_DICT_T')
62 MATRIX_DICT_A = intern('MATRIX_DICT_A')
63 MATRIX_DICT_TA = intern('MATRIX_DICT_TA')
64 MATRIX_DICT_D = intern('MATRIX_DICT_D')
65 MATRIX_DICT_TD = intern('MATRIX_DICT_TD')
67 class MATRIX(HEAD):
68 """ Matrix head singleton class.
70 Usage::
72 MATRIX(<rows>, <cols>, <storage>)
74 where
76 ``<rows>`` - number of matrix rows
77 ``<cols>`` - number of matrix columns
78 ``<strorage>`` - constant describing data storage properties:
79 MATRIX_DICT, MATRIX_DICT_T, MATRIX_DICT_A, MATRIX_DICT_TA,
80 MATRIX_DICT_D, MATRIX_DICT_DT
81 """
83 def __str__ (self):
84 return '%s(%r, %r, %r)' % (self.__class__.__name__, self.rows, self.cols, self.storage)
86 __repr__ = __str__
88 def to_lowlevel(self, cls, data, pair):
89 return pair
91 def init(self, rows, cols, storage):
92 self.rows = rows
93 self.cols = cols
94 self.shape = (rows, cols)
95 self.storage = storage
97 self.is_transpose = is_transpose = storage in [MATRIX_DICT_T, MATRIX_DICT_TA, MATRIX_DICT_TD]
98 self.is_array = storage in [MATRIX_DICT_A, MATRIX_DICT_TA]
99 self.is_diagonal = storage in [MATRIX_DICT_D, MATRIX_DICT_TD]
101 if storage==MATRIX_DICT:
102 self.T = type(self)(cols, rows, MATRIX_DICT_T)
103 self.A = type(self)(rows, cols, MATRIX_DICT_A)
104 self.M = self
105 self.D = type(self)(rows, cols, MATRIX_DICT_D)
106 elif storage==MATRIX_DICT_T:
107 self.T = type(self)(cols, rows, MATRIX_DICT)
108 self.A = type(self)(rows, cols, MATRIX_DICT_TA)
109 self.M = self
110 self.D = type(self)(rows, cols, MATRIX_DICT_TD)
111 elif storage==MATRIX_DICT_A:
112 self.T = type(self)(cols, rows, MATRIX_DICT_TA)
113 self.A = self
114 self.M = type(self)(rows, cols, MATRIX_DICT)
115 self.D = type(self)(rows, cols, MATRIX_DICT_D)
116 elif storage==MATRIX_DICT_TA:
117 self.T = type(self)(cols, rows, MATRIX_DICT_A)
118 self.A = self
119 self.M = type(self)(rows, cols, MATRIX_DICT_T)
120 self.D = type(self)(rows, cols, MATRIX_DICT_TD)
121 elif storage==MATRIX_DICT_D:
122 self.T = type(self)(cols, rows, MATRIX_DICT_T)
123 self.A = type(self)(rows, cols, MATRIX_DICT_A)
124 self.M = type(self)(rows, cols, MATRIX_DICT)
125 self.D = self
126 elif storage==MATRIX_DICT_TD:
127 self.T = type(self)(cols, rows, MATRIX_DICT)
128 self.A = type(self)(rows, cols, MATRIX_DICT_TA)
129 self.M = type(self)(rows, cols, MATRIX_DICT_T)
130 self.D = self
131 else:
132 raise NotImplementedError(`storage`) #pragma NO COVER
134 def totree(obj, tab=''):
135 from .core import Expr
136 if isinstance(obj, Expr):
137 head, data = obj.pair
138 s = '%s%s head:%r\n' % (tab, type(obj).__name__, head)
139 s += '%s' % (totree(data, tab+' '))
140 return s
141 elif isinstance(obj, dict):
142 return '%s%s:\n%s' % (tab, type(obj).__name__, '\n'.join([totree(item, tab+' ') for item in obj.iteritems()]))
143 elif isinstance(obj, (list, tuple)):
144 return '%s%s:\n%s' % (tab, type(obj).__name__, '\n'.join([totree(item, tab+' ') for item in obj]))
145 else:
146 return '%s%s:%r' % (tab, type(obj).__name__, obj)
149 def test_operations(operands, expected_results, unary_operations, binary_operations):
150 from sympycore import Expr
152 results = {}
153 for line in expected_results.split('\n'):
154 line = line.strip()
155 if ':' not in line: continue
156 expr, result = line.split(':')
157 for e in expr.split(';'):
158 e = e.strip()
159 results[e] = [r.strip() for r in result.split(';')]
161 if isinstance(operands, tuple):
162 operands1, operands2 = operands
163 else:
164 operands1 = operands2 = operands
166 for op1 in operands1:
167 if isinstance(op1, Expr):
168 for op in unary_operations:
169 expr = '%s(%s)' % (op, op1)
171 try:
172 result_obj = eval('%s(op1)' % (op), dict(op1=op1))
173 result = str(result_obj)
174 except Exception, msg:
175 print expr,'failed with %s' % (msg)
176 raise
178 if expr not in results:
179 print '%s:%s' % (expr, result)
180 continue
181 try:
182 assert result in results[expr], `results[expr], result`
183 except AssertionError:
184 print
185 print 'op1: %s' % (op1)
186 print totree(op1, ' ')
187 print '%r result: %s' % (op, result_obj)
188 print totree(result_obj, ' ')
189 raise
190 for op2 in operands2:
191 if not (isinstance(op1, Expr) or isinstance(op2, Expr)):
192 continue
193 for op in binary_operations:
194 expr = '(%s)%s(%s)' % (op1, op, op2)
196 result_obj = None
197 try:
198 result_obj = eval('(op1)%s(op2)' % op, dict(op1=op1, op2=op2))
199 result = str(result_obj)
200 except Exception, msg:
201 result = str(msg)
202 if not result.startswith('unsupported'):
203 print expr,`op1,op,op2`,'failed with %s' % (msg)
204 raise
205 if expr not in results:
206 print '%s:%s' % (expr, result)
207 continue
208 if result.startswith('unsupported'):
209 assert 'unsupported' in results[expr], `results[expr], result, op1, op2, expr`
210 else:
211 try:
212 assert result in results[expr], `results[expr], result`
213 except AssertionError:
214 print
215 print 'op1: %s' % (op1)
216 print totree(op1, ' ')
217 print 'op2: %s' % (op2)
218 print totree(op2, ' ')
219 print '%r result: %s' % (op, result_obj)
220 print totree(result_obj, ' ')
221 raise
224 from heads import *