Created
October 29, 2011 18:16
-
-
Save asmeurer/1324886 to your computer and use it in GitHub Desktop.
smichr/and as_numer_denom kernprof
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Wrote profile results to t.py.lprof | |
Timer unit: 1e-06 s | |
File: sympy/core/add.py | |
Function: as_numer_denom at line 285 | |
Total time: 17.2948 s | |
Line # Hits Time Per Hit % Time Line Contents | |
============================================================== | |
285 @profile | |
286 def as_numer_denom(self): | |
287 1 25 25.0 0.0 from sympy import gcd, cancel | |
288 | |
289 10003 1552929 155.2 9.0 numers, denoms = [list(_) for _ in zip(*[f.as_numer_denom() for f in self.args])] | |
290 # for debugging | |
291 # no, do = self._as_numer_denom_expanded(numers, denoms) | |
292 1 4 4.0 0.0 g = G = S.One | |
293 | |
294 # check for trivial case | |
295 1 4 4.0 0.0 denom = denoms[0] | |
296 1 54 54.0 0.0 if all(d == denom for d in denoms): | |
297 n, d = Add(*numers), denom | |
298 g, d = d.as_content_primitive() | |
299 | |
300 # If all denoms are Number use the binary method: this doesn't lead to nesting | |
301 # because the Numbers auto-distribute on the nested terms | |
302 1 9 9.0 0.0 elif all(d.is_Number for d in denoms): | |
303 n, d = self._as_numer_denom_binary(numers, denoms) | |
304 | |
305 else: | |
306 # simple gcd extraction (no factoring beyond primitive nor expanding) | |
307 10001 71604 7.2 0.4 denoms = [list(d.as_content_primitive()) for d in denoms] | |
308 | |
309 1 3 3.0 0.0 g = G = S.Zero | |
310 1 4 4.0 0.0 hit = True | |
311 2 11 5.5 0.0 for i, d in enumerate(denoms): | |
312 2 1522 761.0 0.0 g = gcd(g, d[0]) | |
313 6 86 14.3 0.0 c, nc = [Mul._from_args(list(w)) for w in d[1].args_cnc()] | |
314 2 12 6.0 0.0 denoms[i] = [d[0], c, nc] | |
315 2 3359 1679.5 0.0 G = gcd(c, G) | |
316 2 41 20.5 0.0 if g == G == S.One: | |
317 10000 31329 3.1 0.2 for i in range(i, len(denoms)): | |
318 9999 34333 3.4 0.2 denoms[i].append(S.One) | |
319 1 5 5.0 0.0 break | |
320 1 4 4.0 0.0 if g is not S.One: | |
321 for i, d in enumerate(denoms): | |
322 denoms[i][0] /= g | |
323 1 3 3.0 0.0 if G is not S.One: | |
324 for i, d in enumerate(denoms): | |
325 denoms[i][0] /= G | |
326 10001 402466 40.2 2.3 denoms = [Mul(*d) for d in denoms] | |
327 # make sure that there are no denominators introduced | |
328 1 7 7.0 0.0 if G is not S.One: | |
329 for i, d in enumerate(denoms): | |
330 for m in Mul.make_args(d): | |
331 if m.is_Pow and m.exp.is_Integer and m.exp < 0: | |
332 denoms[i] = cancel(d) | |
333 break | |
334 | |
335 # collect common denominators | |
336 1 5 5.0 0.0 n = len(numers) | |
337 1 4 4.0 0.0 d = {} | |
338 10001 31554 3.2 0.2 for i in xrange(len(numers)): | |
339 10000 70223 7.0 0.4 d.setdefault(denoms[i], []).append(numers[i]) | |
340 1 103 103.0 0.0 denoms = d.keys() | |
341 1001 222989 222.8 1.3 numers = [Add(*d[di]) for di in denoms] | |
342 | |
343 # if a gcd was taken, check to see if the length of | |
344 # denoms is 1 | |
345 1 4 4.0 0.0 if len(denoms) == 1: | |
346 n, d = numers[0], denoms[0] | |
347 | |
348 # If the time needed to expand the nested numerator can be decreased then | |
349 # the elif-else would not be necessary: the binary method could always be used. | |
350 1 4 4.0 0.0 elif len(denoms) != n or \ | |
351 any(d.is_Add or d.is_Mul and any(di.is_Add for di in d.args) | |
352 for d in denoms): | |
353 # use binary method because a) if we collected denoms, it is | |
354 # better to group them so we don't have to cancel common | |
355 # terms in numer and denom or b) there would have been nesting | |
356 # anyway if there was an Add present | |
357 1 4554898 4554898.0 26.3 n, d = self._as_numer_denom_binary(numers, denoms) | |
358 1 39 39.0 0.0 del numers, denoms # they've changed | |
359 else: | |
360 ## >>> n=300; num, den = [1]*n, [Dummy() for i in range(n)] | |
361 ## the following takes about 9 seconds (7 for numerator) | |
362 ## >>> ok=expand_mul(a._as_numer_denom_expanded(num, den)[0]) | |
363 ## the following takes 16 seconds (but less than 1 for numerator) | |
364 ## >>> ok=expand_mul(a._as_numer_denom_binary(num, den)[0]) | |
365 n, d = self._as_numer_denom_expanded(numers, denoms) | |
366 | |
367 1 5 5.0 0.0 if d.is_Rational: | |
368 g *= d | |
369 else: | |
370 1 2766 2766.0 0.0 G *= d | |
371 | |
372 # for debugging | |
373 # n1, d1 = n, g*G | |
374 # assert (no*d1-n1*do).expand() == 0 | |
375 | |
376 # expr -> n/(g*G) = (c*ni)/(g*G) = (c/g)*ni/G = (cn*ni)/(cd*G) | |
377 1 10313827 10313827.0 59.6 c, ni = n.as_content_primitive() | |
378 1 384 384.0 0.0 cn, cd = (c/g).as_numer_denom() | |
379 1 159 159.0 0.0 n, d = cn*ni, cd*G | |
380 | |
381 # for debugging | |
382 # assert (no*d-n*do).expand() == 0 | |
383 | |
384 1 3 3.0 0.0 return n, d | |
File: sympy/core/add.py | |
Function: as_content_primitive at line 742 | |
Total time: 7.6969 s | |
Line # Hits Time Per Hit % Time Line Contents | |
============================================================== | |
742 @profile | |
743 def as_content_primitive(self): | |
744 """Return the tuple (R, self/R) where R is the positive Rational | |
745 extracted from self. | |
746 | |
747 **Example** | |
748 >>> from sympy import sqrt | |
749 >>> (3 + 3*sqrt(2)).as_content_primitive() | |
750 (3, 1 + sqrt(2)) | |
751 | |
752 See docstring of Expr.as_content_primitive for more examples. | |
753 """ | |
754 1999 15500 7.8 0.2 from sympy import gcd | |
755 13997 229414 16.4 3.0 c_args = [a.as_content_primitive() for a in self.args] | |
756 13997 6338038 452.8 82.3 g = reduce(gcd, [c[0] for c in c_args]) | |
757 1999 6080 3.0 0.1 if g is S.One: | |
758 13997 1064844 76.1 13.8 a = Add(*[c[0]*c[1] for c in c_args]) | |
759 else: | |
760 a = Add(*[c[0]/g*c[1] for c in c_args]) | |
761 1999 6850 3.4 0.1 c, ai = a.as_coeff_Mul() | |
762 1999 3565 1.8 0.0 if c.is_Rational: | |
763 1999 3032 1.5 0.0 if c.is_negative: | |
764 c = -c | |
765 ai = -ai | |
766 1999 24052 12.0 0.3 g *= c | |
767 1999 3046 1.5 0.0 a = ai | |
768 else: | |
769 a *= g | |
770 g = S.One | |
771 1999 2484 1.2 0.0 return g, a |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Wrote profile results to t.py.lprof | |
Timer unit: 1e-06 s | |
File: sympy/core/add.py | |
Function: as_numer_denom at line 285 | |
Total time: 12.7791 s | |
Line # Hits Time Per Hit % Time Line Contents | |
============================================================== | |
285 @profile | |
286 def as_numer_denom(self): | |
287 1 25 25.0 0.0 from sympy import gcd, cancel | |
288 | |
289 10003 1446485 144.6 11.3 numers, denoms = [list(_) for _ in zip(*[f.as_numer_denom() for f in self.args])] | |
290 # for debugging | |
291 # no, do = self._as_numer_denom_expanded(numers, denoms) | |
292 1 3 3.0 0.0 g = G = S.One | |
293 | |
294 # check for trivial case | |
295 1 4 4.0 0.0 denom = denoms[0] | |
296 1 41 41.0 0.0 if all(d == denom for d in denoms): | |
297 n, d = Add(*numers), denom | |
298 g, d = d.as_content_primitive() | |
299 | |
300 # If all denoms are Number use the binary method: this doesn't lead to nesting | |
301 # because the Numbers auto-distribute on the nested terms | |
302 1 8 8.0 0.0 elif all(d.is_Number for d in denoms): | |
303 n, d = self._as_numer_denom_binary(numers, denoms) | |
304 | |
305 else: | |
306 # simple gcd extraction (no factoring beyond primitive nor expanding) | |
307 10001 68835 6.9 0.5 denoms = [list(d.as_content_primitive()) for d in denoms] | |
308 | |
309 1 4 4.0 0.0 g = G = S.Zero | |
310 1 3 3.0 0.0 hit = True | |
311 2 12 6.0 0.0 for i, d in enumerate(denoms): | |
312 2 1767 883.5 0.0 g = gcd(g, d[0]) | |
313 6 90 15.0 0.0 c, nc = [Mul._from_args(list(w)) for w in d[1].args_cnc()] | |
314 2 8 4.0 0.0 denoms[i] = [d[0], c, nc] | |
315 2 3957 1978.5 0.0 G = gcd(c, G) | |
316 2 46 23.0 0.0 if g == G == S.One: | |
317 10000 35267 3.5 0.3 for i in range(i, len(denoms)): | |
318 9999 39438 3.9 0.3 denoms[i].append(S.One) | |
319 1 4 4.0 0.0 break | |
320 1 3 3.0 0.0 if g is not S.One: | |
321 for i, d in enumerate(denoms): | |
322 denoms[i][0] /= g | |
323 1 3 3.0 0.0 if G is not S.One: | |
324 for i, d in enumerate(denoms): | |
325 denoms[i][0] /= G | |
326 10001 438608 43.9 3.4 denoms = [Mul(*d) for d in denoms] | |
327 # make sure that there are no denominators introduced | |
328 1 5 5.0 0.0 if G is not S.One: | |
329 for i, d in enumerate(denoms): | |
330 for m in Mul.make_args(d): | |
331 if m.is_Pow and m.exp.is_Integer and m.exp < 0: | |
332 denoms[i] = cancel(d) | |
333 break | |
334 | |
335 # collect common denominators | |
336 1 5 5.0 0.0 n = len(numers) | |
337 1 4 4.0 0.0 d = {} | |
338 10001 32258 3.2 0.3 for i in xrange(len(numers)): | |
339 10000 71519 7.2 0.6 d.setdefault(denoms[i], []).append(numers[i]) | |
340 1 111 111.0 0.0 denoms = d.keys() | |
341 1001 221585 221.4 1.7 numers = [Add(*d[di]) for di in denoms] | |
342 | |
343 # if a gcd was taken, check to see if the length of | |
344 # denoms is 1 | |
345 1 4 4.0 0.0 if len(denoms) == 1: | |
346 n, d = numers[0], denoms[0] | |
347 | |
348 # If the time needed to expand the nested numerator can be decreased then | |
349 # the elif-else would not be necessary: the binary method could always be used. | |
350 1 3 3.0 0.0 elif len(denoms) != n or \ | |
351 any(d.is_Add or d.is_Mul and any(di.is_Add for di in d.args) | |
352 for d in denoms): | |
353 # use binary method because a) if we collected denoms, it is | |
354 # better to group them so we don't have to cancel common | |
355 # terms in numer and denom or b) there would have been nesting | |
356 # anyway if there was an Add present | |
357 1 5139208 5139208.0 40.2 n, d = self._as_numer_denom_binary(numers, denoms) | |
358 1 43 43.0 0.0 del numers, denoms # they've changed | |
359 else: | |
360 ## >>> n=300; num, den = [1]*n, [Dummy() for i in range(n)] | |
361 ## the following takes about 9 seconds (7 for numerator) | |
362 ## >>> ok=expand_mul(a._as_numer_denom_expanded(num, den)[0]) | |
363 ## the following takes 16 seconds (but less than 1 for numerator) | |
364 ## >>> ok=expand_mul(a._as_numer_denom_binary(num, den)[0]) | |
365 n, d = self._as_numer_denom_expanded(numers, denoms) | |
366 | |
367 1 5 5.0 0.0 if d.is_Rational: | |
368 g *= d | |
369 else: | |
370 1 2243 2243.0 0.0 G *= d | |
371 | |
372 # for debugging | |
373 # n1, d1 = n, g*G | |
374 # assert (no*d1-n1*do).expand() == 0 | |
375 | |
376 # expr -> n/(g*G) = (c*ni)/(g*G) = (c/g)*ni/G = (cn*ni)/(cd*G) | |
377 1 5277179 5277179.0 41.3 c, ni = n.as_content_primitive() | |
378 1 189 189.0 0.0 cn, cd = (c/g).as_numer_denom() | |
379 1 155 155.0 0.0 n, d = cn*ni, cd*G | |
380 | |
381 # for debugging | |
382 # assert (no*d-n*do).expand() == 0 | |
383 | |
384 1 3 3.0 0.0 return n, d | |
File: sympy/core/add.py | |
Function: as_content_primitive at line 742 | |
Total time: 2.02115 s | |
Line # Hits Time Per Hit % Time Line Contents | |
============================================================== | |
742 @profile | |
743 def as_content_primitive(self): | |
744 """Return the tuple (R, self/R) where R is the positive Rational | |
745 extracted from self. | |
746 | |
747 **Example** | |
748 >>> from sympy import sqrt | |
749 >>> (3 + 3*sqrt(2)).as_content_primitive() | |
750 (3, 1 + sqrt(2)) | |
751 | |
752 See docstring of Expr.as_content_primitive for more examples. | |
753 """ | |
754 1999 15486 7.7 0.8 from sympy import gcd_list | |
755 13997 278525 19.9 13.8 c_args = [a.as_content_primitive() for a in self.args] | |
756 13997 424152 30.3 21.0 g = gcd_list([c[0] for c in c_args]) | |
757 1999 3555 1.8 0.2 if g is S.One: | |
758 13997 1232919 88.1 61.0 a = Add(*[c[0]*c[1] for c in c_args]) | |
759 else: | |
760 a = Add(*[c[0]/g*c[1] for c in c_args]) | |
761 1999 8043 4.0 0.4 c, ai = a.as_coeff_Mul() | |
762 1999 2851 1.4 0.1 if c.is_Rational: | |
763 1999 4413 2.2 0.2 if c.is_negative: | |
764 c = -c | |
765 ai = -ai | |
766 1999 44520 22.3 2.2 g *= c | |
767 1999 4107 2.1 0.2 a = ai | |
768 else: | |
769 a *= g | |
770 g = S.One | |
771 1999 2584 1.3 0.1 return g, a | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment