|
97 | 97 | from sage.rings.integer_ring import ZZ
|
98 | 98 | from sage.rings.infinity import infinity
|
99 | 99 | from sage.arith.misc import divisors
|
| 100 | +from sage.misc.misc_c import prod |
100 | 101 | from sage.combinat.integer_vector_weighted import iterator_fast as wt_int_vec_iter
|
101 | 102 |
|
102 | 103 | class Stream():
|
@@ -2347,7 +2348,7 @@ def __init__(self, series, shift):
|
2347 | 2348 | sage: from sage.data_structures.stream import Stream_exact
|
2348 | 2349 | sage: h = Stream_exact([1], False, constant=3)
|
2349 | 2350 | sage: M = Stream_shift(h, 2)
|
2350 |
| - sage: TestSuite(M).run() |
| 2351 | + sage: TestSuite(M).run(skip="_test_pickling") |
2351 | 2352 | """
|
2352 | 2353 | self._series = series
|
2353 | 2354 | self._shift = shift
|
@@ -2424,3 +2425,113 @@ def is_nonzero(self):
|
2424 | 2425 | True
|
2425 | 2426 | """
|
2426 | 2427 | return self._series.is_nonzero()
|
| 2428 | + |
| 2429 | +class Stream_derivative(Stream_inexact): |
| 2430 | + """ |
| 2431 | + Operator for taking derivatives of a stream. |
| 2432 | +
|
| 2433 | + INPUT: |
| 2434 | +
|
| 2435 | + - ``series`` -- a :class:`Stream` |
| 2436 | + - ``shift`` -- a positive integer |
| 2437 | + """ |
| 2438 | + def __init__(self, series, shift): |
| 2439 | + """ |
| 2440 | + Initialize ``self``. |
| 2441 | +
|
| 2442 | + EXAMPLES:: |
| 2443 | +
|
| 2444 | + sage: from sage.data_structures.stream import Stream_exact, Stream_derivative |
| 2445 | + sage: f = Stream_exact([1,2,3], False) |
| 2446 | + sage: f2 = Stream_derivative(f, 2) |
| 2447 | + sage: TestSuite(f2).run() |
| 2448 | + """ |
| 2449 | + self._series = series |
| 2450 | + self._shift = shift |
| 2451 | + if 0 <= series._approximate_order <= shift: |
| 2452 | + aorder = 0 |
| 2453 | + else: |
| 2454 | + aorder = series._approximate_order - shift |
| 2455 | + super().__init__(series._is_sparse, aorder) |
| 2456 | + |
| 2457 | + def __getitem__(self, n): |
| 2458 | + """ |
| 2459 | + Return the ``n``-th coefficient of ``self``. |
| 2460 | +
|
| 2461 | + EXAMPLES:: |
| 2462 | +
|
| 2463 | + sage: from sage.data_structures.stream import Stream_function, Stream_derivative |
| 2464 | + sage: f = Stream_function(lambda n: 1/n if n else 0, QQ, True, -2) |
| 2465 | + sage: [f[i] for i in range(-5, 3)] |
| 2466 | + [0, 0, 0, -1/2, -1, 0, 1, 1/2] |
| 2467 | + sage: f2 = Stream_derivative(f, 2) |
| 2468 | + sage: [f2[i] for i in range(-5, 3)] |
| 2469 | + [0, -3, -2, 0, 0, 1, 2, 3] |
| 2470 | +
|
| 2471 | + sage: f = Stream_function(lambda n: 1/n, QQ, True, 2) |
| 2472 | + sage: [f[i] for i in range(-1, 4)] |
| 2473 | + [0, 0, 0, 1/2, 1/3] |
| 2474 | + sage: f2 = Stream_derivative(f, 3) |
| 2475 | + sage: [f2[i] for i in range(-1, 4)] |
| 2476 | + [0, 2, 6, 12, 20] |
| 2477 | + """ |
| 2478 | + return (prod(n+k for k in range(1, self._shift + 1)) |
| 2479 | + * self._series[n + self._shift]) |
| 2480 | + |
| 2481 | + def __hash__(self): |
| 2482 | + """ |
| 2483 | + Return the hash of ``self``. |
| 2484 | +
|
| 2485 | + EXAMPLES:: |
| 2486 | +
|
| 2487 | + sage: from sage.data_structures.stream import Stream_function |
| 2488 | + sage: from sage.data_structures.stream import Stream_derivative |
| 2489 | + sage: a = Stream_function(lambda n: 2*n, ZZ, False, 1) |
| 2490 | + sage: f = Stream_derivative(a, 1) |
| 2491 | + sage: g = Stream_derivative(a, 2) |
| 2492 | + sage: hash(f) == hash(f) |
| 2493 | + True |
| 2494 | + sage: hash(f) == hash(g) |
| 2495 | + False |
| 2496 | +
|
| 2497 | + """ |
| 2498 | + return hash((type(self), self._series, self._shift)) |
| 2499 | + |
| 2500 | + def __eq__(self, other): |
| 2501 | + """ |
| 2502 | + Test equality. |
| 2503 | +
|
| 2504 | + INPUT: |
| 2505 | +
|
| 2506 | + - ``other`` -- a stream of coefficients |
| 2507 | +
|
| 2508 | + EXAMPLES:: |
| 2509 | +
|
| 2510 | + sage: from sage.data_structures.stream import Stream_function |
| 2511 | + sage: from sage.data_structures.stream import Stream_derivative |
| 2512 | + sage: a = Stream_function(lambda n: 2*n, ZZ, False, 1) |
| 2513 | + sage: f = Stream_derivative(a, 1) |
| 2514 | + sage: g = Stream_derivative(a, 2) |
| 2515 | + sage: f == g |
| 2516 | + False |
| 2517 | + sage: f == Stream_derivative(a, 1) |
| 2518 | + True |
| 2519 | + """ |
| 2520 | + return (isinstance(other, type(self)) and self._shift == other._shift |
| 2521 | + and self._series == other._series) |
| 2522 | + |
| 2523 | + def is_nonzero(self): |
| 2524 | + r""" |
| 2525 | + Return ``True`` if and only if this stream is known |
| 2526 | + to be nonzero. |
| 2527 | +
|
| 2528 | + EXAMPLES:: |
| 2529 | +
|
| 2530 | + sage: from sage.data_structures.stream import Stream_exact, Stream_derivative |
| 2531 | + sage: f = Stream_exact([1,2], False) |
| 2532 | + sage: Stream_derivative(f, 1).is_nonzero() |
| 2533 | + True |
| 2534 | + sage: Stream_derivative(f, 2).is_nonzero() # it might be nice if this gave False |
| 2535 | + True |
| 2536 | + """ |
| 2537 | + return self._series.is_nonzero() |
0 commit comments