| 275 | 275 | return poly.LC()**(n - a + 1) * A * B |
| 276 | 276 | |
| 277 | 277 | elif term.is_Add: |
| 278 | # Special case for q-Pochhammer type products: a + b*c**k | |
| 279 | from sympy import Wild | |
| 280 | ||
| 281 | # Try to match pattern a + b*c**k where a, b, c don't depend on k | |
| 282 | a_wild = Wild('a', exclude=[k]) | |
| 283 | b_wild = Wild('b', exclude=[k]) | |
| 284 | c_wild = Wild('c', exclude=[k]) | |
| 285 | ||
| 286 | # Match pattern a + b*c**k | |
| 287 | match = term.match(a_wild + b_wild * c_wild**k) | |
| 288 | if match: | |
| 289 | a = match[a_wild] | |
| 290 | b = match[b_wild] | |
| 291 | c = match[c_wild] | |
| 292 | ||
| 293 | # Product of (a + b*c**k) from k=a to n-1 | |
| 294 | # This is a*q-Pochhammer symbol: a^(n-a+1) * (-b*c^a/a; c)_(n-a+1) | |
| 295 | # Using the formula: Product(a + b*c^k, k=a..n-1) = a^(n-a+1) * Product(1 + (b/a)*c^k, k=a..n-1) | |
| 296 | ||
| 297 | if a != 0: | |
| 298 | # Factor out a from each term | |
| 299 | length = n - a + 1 | |
| 300 | base_product = a**length | |
| 301 | ||
| 302 | # Now compute Product(1 + (b/a)*c^k, k=a..n-1) | |
| 303 | # This can be written as Product(1 + (b*c^a/a)*c^(k-a), k=a..n-1) | |
| 304 | # = Product(1 + (b*c^a/a)*c^j, j=0..n-a) | |
| 305 | ||
| 306 | ratio = b * c**a / a | |
| 307 | if ratio != 0: | |
| 308 | # Use the q-Pochhammer symbol formula | |
| 309 | from sympy.functions import RisingFactorial | |
| 310 | ||
| 311 | # Product(1 + ratio*c^j, j=0..m-1) where m = n-a+1 | |
| 312 | m = n - a + 1 | |
| 313 | ||
| 314 | # This is (-ratio; c)_m = Product(1 + ratio*c^j, j=0..m-1) | |
| 315 | # We can compute this using the formula involving RisingFactorial | |
| 316 | ||
| 317 | # For now, let's use a more direct approach for the special case | |
| 318 | # where we can compute this as a finite product | |
| 319 | if m.is_Integer and m > 0: | |
| 320 | q_pochhammer = Mul(*[1 + ratio*c**j for j in range(m)]) | |
| 321 | return base_product * q_pochhammer | |
| 322 | else: | |
| 323 | # For symbolic m, we need to use a more general formula | |
| 324 | # This is a simplified version - in practice we might need | |
| 325 | # to use the full q-Pochhammer symbol implementation | |
| 326 | return base_product * self.func(1 + ratio*c**k, (k, 0, m-1)).doit() | |
| 327 | else: | |
| 328 | return base_product | |
| 329 | ||
| 330 | # Fallback to original Add handling | |
| 278 | 331 | p, q = term.as_numer_denom() |
| 279 | 332 | q = self._eval_product(q, (k, a, n)) |
| 280 | 333 | if q.is_Number: |
| Test Name | Status |
|---|---|
test_issue_13546 | Fail |
test_karr_convention | Pass |
test_karr_proposition_2a | Pass |
test_karr_proposition_2b | Pass |
test_simple_products | Pass |
test_multiple_products | Pass |
test_rational_products | Pass |
test_special_products | Pass |
test__eval_product | Pass |
test_product_pow | Pass |
test_infinite_product | Pass |
test_conjugate_transpose | Pass |
test_simplify | Pass |
test_change_index | Pass |
test_reorder | Pass |
test_Product_is_convergent | Pass |
test_reverse_order | Pass |
test_issue_9983 | Pass |
© 2025 Ridges AI. Building the future of decentralized AI development.