File: rtest_powerseries.mac

package info (click to toggle)
maxima-sage 5.45.1-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 113,788 kB
  • sloc: lisp: 440,833; fortran: 14,665; perl: 14,369; tcl: 10,997; sh: 4,475; makefile: 2,520; ansic: 447; python: 262; xml: 59; awk: 37; sed: 17
file content (355 lines) | stat: -rw-r--r-- 10,610 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
/*
  test_powerseries.mac

  Tests for the powerseries() function
*/

kill(all);
done$

/*
  Basic identities
*/
powerseries(a, x, 0);
a$

powerseries(x, x, 0);
x$

/* Check that we get an error if the variable is a non-symbol atom */
errcatch(powerseries(x, 0, 0));
[]$

errcatch(powerseries(x, "foo", 0));
[]$

/* Check we distribute over bags */
niceindices(powerseries([sin(x), cos(x)], x, 0));
''(niceindices([powerseries(sin(x), x, 0), powerseries(cos(x), x, 0)]))$

/* Check we distribute over sum() and product() */
niceindices(powerseries(sum(f(x,i), i, 0, inf), x, 0));
''(niceindices(sum(powerseries(f(x,i), x, 0), i, 0, inf)));

niceindices(powerseries(product(f(x,i), i, 0, inf), x, 0));
''(niceindices(product(powerseries(f(x,i), x, 0), i, 0, inf)));


/* Check that we can expand with respect to a non-atomic expression
   (or at least check that we do something vaguely sensible) */
niceindices(powerseries(sin(x^2), x^2, 0) - powerseries(sin(x^2), x, 0));
0$

/* Check that sums get expanded sanely (in SP1) */
niceindices(powerseries(a + sin(x), x, 0) - powerseries(sin(x), x, 0));
a$

/* An element of the transformation dictionary for special trig sums in SP1 */
niceindices(powerseries (1+tan(x)^2, x, 0) - powerseries(sec(x)^2, x, 0));
0$

/* Check that constant factors get pulled out (in SP1TIMES) */
niceindices(powerseries(a*sin(x), x, 0) - a*powerseries(sin(x), x, 0));
0$

/* ... even if they aren't atoms. */
niceindices(powerseries((a+b)*sin(x), x, 0) - (a+b)*powerseries(sin(x), x, 0));
0$

/* "Atomic" factors also get pulled out */
niceindices(powerseries(x*sin(x), x, 0) - x*powerseries(sin(x), x, 0));
0$

/* Check that we evaluate powerseries at inf and minf sensibly */
powerseries(1/x, x, inf);
1/x$

powerseries(1/x, x, minf);
1/x$

/*
  Exponentiation of a sum is dealt with in SRBINEXPAND, which has to
  cope with various possibilities depending on how much we know about
  which terms are nonzero.
*/
powerseries(x^y^z, x, 0);
x^y^z$

(declare([int, posint], integer),
 assume(posint > 0),
 assume(pos > 0),
 assume(notequal(nz, 0)),
 assume(equal(zero, 0)), 0);
0$

powerseries((x^y+1)^zero, x, 0);
1$

powerseries((zero*x + 2)^y, x, 0);
2^y$

powerseries((x + zero)^y, x, 0);
x^y$

niceindices(powerseries((nz + 1)^n, nz, 0));
'sum(nz^i/beta(i+1, n-i+1), i, 0, inf)/(n+1)$

niceindices(powerseries((nz + 1)^posint, nz, 0));
'sum(nz^i/beta(i+1, posint-i+1), i, 0, posint)/(posint+1)$

niceindices(powerseries((nz + 1)^k, nz, 0));
'sum(nz^i/beta(i+1, k-i+1), i, 0, inf)/(k+1)$

niceindices(powerseries((x + 1)^k, x, 0));
1 + 'sum(x^i/beta(i+1, k-i+1), i, 1, inf)/(k+1)$

niceindices(powerseries((x + u)^posint, x, 0));
('sum(x^i*u^(posint-i)/beta(i+1, posint-i+1),
      i, 0, posint-1) / (posint+1)) + x^posint$

powerseries((x + y)^k, x, 0);
'powerseries((x + y)^k, x, 0)$

/* Some more white-box tests, based on the structure of SRATEXPND */

/* If the numerator is monomial, factor it out and recurse */
niceindices(powerseries(a*x^u/(1+x), x, 0) - a*x^u*powerseries(1/(1+x), x, 0));
0$

/* If the denominator is free of x and the numerator is a polynomial,
   return the quotient */
powerseries((x^2 + x + 1)/(a + b + c), x, 0);
(x^2 + x + 1)/(a + b + c)$

/*
  If the denominator is free of y, but the numerator is sufficiently
  gnarly, we give up. (Obviously, it would be nice to do better here!)
*/
powerseries((x+x^(1+y)+1)/(2+y), x, 0);
powerseries((x+x^(1+y)+1)/(2+y), x, 0)$

/*
  Another gnarly example we can't deal with. We can't use partial
  fraction expansion because we don't know that k < 2 (and, even if we
  did, I don't know how we'd parametrise the result on k).
*/
powerseries((x+1)^k/((x+2)*(x+3)), x, 0);
powerseries((x+1)^k/((x+2)*(x+3)), x, 0)$

/* The only way of getting a monomial denominator in sratexpnd is if
   the numerator is a polynomial. If the denominator is a sum, we return the
   sum of quotients: */
powerseries((x^2 + x + 1)/(a*x^2), x, 0);
1/a + 1/(a*x) + 1/(a*x^2)$

/* If the denominator isn't a sum, we just return the quotient of the
   top and bottom. */
powerseries((1+x)^n/(a*x^2), x, 0);
(1+x)^n/(a*x^2)$

/* (I haven't yet managed to find an example that triggers the
    SRATSUBST clause and doesn't yield a noun form) */

/* Partial fraction expansion */
niceindices(powerseries(1/((1-2*x)*(1-3*x)), x, 0));
'sum((3^(i+1) - 2^(i+1))*x^i, i, 0, inf)$

/*
  Make sure we give up (rather than possibly recursing infinitely) in
  the general case at the bottom of SRATEXPND.
*/
powerseries((x+2)*(x+3)^k/(x*(x+4)), x, 0);
powerseries((x+2)*(x+3)^k/(x*(x+4)), x, 0)$

/*
  A complicated example of a partial fraction expansion. The expansion
  into partial fractions is 1 + 2/(x+3) - 6/(x+4), and the terms then
  expand into two infinite series and one constant term. This test
  makes sure that we coalesce the two series properly (in PSP2FOLDSUM).
*/
factor(niceindices(powerseries((x+1)*(x+2)/((x+3)*(x+4)), x, 0)));
(sum(3^(-i-1)*(-1)^i*(4^(i+1)-3^(i+2))*x^i/4^i,i,0,inf)+2)/2$

/*
  Make sure we successfully remove zero roots from the denominator
  before trying to expand partial fractions.
*/
niceindices(powerseries((x+2)*(x+3)/(x^2*(x+1)^k), x, 0)*x^2 -
            powerseries((x+2)*(x+3)/(x+1)^k, x, 0));
0$

/* Fixed in series.lisp rev 1.5, 04 Feb 2004.
   First case returned second result */
niceindices(powerseries(1/sqrt(1 + x), x, 0));
1 + 2*'sum(x^i/beta(1/2-i,i+1),i,1,inf);
niceindices (powerseries(sqrt(1+x),x,0));
1 + 2*('sum(x^i/beta(3/2-i,i+1),i,1,inf))/3;

/* sf bug 1730044 - powerseries(1+x^n,x,0) wrong; see also #2764 power series of 1 + x^n */
powerseries(1+x^n, x, 0);
1+x^n$

(gensumnum : 0, declare(n, integer), powerseries(1/(1+x^n), x, 0));
'sum((-1)^i1*x^(i1*n),i1,0,inf)$

/* #2756 powerseries of constant plus power of linear  */
(gensumnum : 0, powerseries(1 + (1-x)^(1/3),x,0));
(3*sum(((-1)^i1*x^i1)/beta(4/3-i1,i1+1),i1,1,inf))/4+2$

/* Examples from SF bug report [ 1722156 ] powerseries((x+1)/(1-2*x^2), x, 0);
 * tnx Dan Gildea
 */

gensumnum : 0;
0;

/* two simple roots */
powerseries((1)/((1-2*x)*(1-3*x)), x, 0);
'sum((3^(i1+1)+(-2*2^i1))*x^i1,i1,0,inf);

/* fibonacci */
powerseries((1)/(1-x-x^2), x, 0);
-'sum((-2*(sqrt(5)-1)^(-i2-1)*2^i2/sqrt(5)
 -2*(sqrt(5)+1)^(-i2-1)*(-2)^i2/sqrt(5))
 *x^i2,i2,0,inf);

/* 1 1 2 2 4 4 8 8 */
factor(powerseries((1+x)/(1-2*x^2), x, 0));
/*
'sum( (-1*(1/-(1/sqrt(2)))*(1/sqrt(2)-1)*(1/-(4/sqrt(2)))*(1/-(1/sqrt(2)))^i3 +
      -1*(1/(1/sqrt(2)))*(-1/sqrt(2)-1)*(1/(4/sqrt(2)))*(1/(1/sqrt(2)))^i3 ) * x^i3,i3,0,inf);
*/

'sum(2^(i3/2-3/2)*((sqrt(2)-1)*(-1)^i3+sqrt(2)+1)*x^i3,i3,0,inf);

/* multiple root */
powerseries((1+x)/(1-x)^2, x, 0);
'sum(2*(i4+1)*x^i4-x^i4,i4,0,inf);

/* numerator higher order poly than denom */
powerseries((1+x^3)/(1-x-x^2), x, 0);
-2*x
 *'sum((-2*(sqrt(5)-1)^(-i5-1)*2^i5/sqrt(5)
   -2*(sqrt(5)+1)^(-i5-1)*(-2)^i5/sqrt(5))
   *x^i5,i5,0,inf)
  -x+1;

/* zero root in denom */
powerseries((1)/((1-2*x)*(x)), x, 0);
('sum(2^i6*x^i6,i6,0,inf))/x;

/* one simple and one repeated root in denom */
powerseries((1+x+x^2)/((1-2*x)*(1+x)^2), x, 0);
'sum(7*2^i7*x^i7/9+(i7+1)*(-1)^i7*x^i7/3-(-1)^i7*x^i7/9,i7,0,inf);

/* gcd of exps is two */
powerseries((1-x^2)/(1-4*x^2+x^4), x, 0);
'sum((-1*(1/(2-sqrt(3)))*(sqrt(3)-1)*(1/(2*(2-sqrt(3))-4))*(1/(2-sqrt(3)))^i8 +
      -1*(1/(sqrt(3)+2))*(-sqrt(3)-1)*(1/(2*(sqrt(3)+2)-4))*(1/(sqrt(3)+2))^i8 )*x^(2*i8),
      i8, 0, inf);

/* #2750 powerseries(x^x,x,0) gives Lisp error */
powerseries(x^x, x, 0);
'powerseries(x^x, x, 0)$

sumcontract(intosum(powerseries(1+ (1-x)^(a),x,0) - powerseries((1-x)^(a),x,0)));
1$

/*
  #2775: Don't expand a powerseries with log(ab)=log(a)+log(b) if a
         is negative

  (and also #2767)
*/
(gensumnum : 0, powerseries (log(2-x), x, 0));
log(2) - sum (2^(-i2-1)*x^(i2+1)/(i2+1), i2, 0, inf)$

/*
  #2760: powerseries at minf

  For an analytic function like this, the power series at minf should
  match the power series at inf.
*/
block([inf_exp, minf_exp],
  gensumnum : 0,
  inf_exp: powerseries (1/(1+x), x, inf),
  gensumnum : 0,
  minf_exp: powerseries (1/(1+x), x, inf),
  inf_exp - minf_exp);
0$

/* #2765: powerseries with non-integer order */
powerseries (diff (f(x), x, biggles), x, 0);
'powerseries (diff (f(x), x, biggles), x, 0)$

/* #2755: powerseries of natural exponential */
niceindices (powerseries (%e^x, x, 1));
sum (1/i!, i, 0, inf) * sum((x-1)^i/i!, i, 0, inf)$

/*
  #2760

  Make sure that we give up rather than trying to substitute an
  arbitrary expression for an integration / differentiation variable
  after expansion.
*/
powerseries(f(x), x, inf);
'powerseries(f(x), x, inf)$

/*
  The test above gives up when it sees either an integral or a
  derivative wrt the expansion variable as it's trying to substitute
  answers back in. Make sure that we still allow either with respect
  to some other variable. (Expand somewhere other than zero, otherwise
  we skip the substitution step)
*/
factor(powerseries(integrate(f(x), x)*y, y, 1));
'integrate(f(x), x)*y$

niceindices(powerseries(log(sin(x)/x),x,0));
/*('sum((-1)^i1*2^(2*i1)*bern(2*i1)*x^(2*i1)/(i1*(2*i1)!),i1,1,inf))/2$*/
'sum((-1)^i*2^(2*i-1)*bern(2*i)*x^(2*i)/(i*(2*i)!),i,1,inf);

/*
  Check that we don't substitute blindly into the bound variables in
  at() expressions.

  The powerseries expands the integral of f(x) by computing an
  antiderivative of the power series of f(x). Since we don't know
  anything about f, this contains terms like "at(diff(f(x), x, n),
  x=0)". If we then substituted the endpoints blindly, we'd get an
  error from substituting in a number as a differentiation variable.
*/
op(niceindices(powerseries(integrate(f(x), x, 0, y), y, 0)));
''(nounify('sum))$

/*
  Check we get a noun form (rather than something exploding) when
  expanding a known power series and then trying to substitute in some
  arbitrary function. At the moment, we only support arguments that
  are monomials (see SP2SUB in series.lisp).
*/
powerseries(sin(f(x)), x, 0);
powerseries(sin(f(x)), x, 0)$

/* Basic support for expanding log(1+x) */
factor(sumcontract(intosum(powerseries(log(x+1), x, 0) -
                           sum((-1)^(i+1)*x^i/i, i, 1, inf))));
0$

/* Check that we can expand log(1+a*x^k) for various a and k. */
niceindices(powerseries(log(1+a*x), x, 0));
-sum((-1)^i * a^i * x^i / i, i, 1, inf)$

niceindices(powerseries(log(1-a*x), x, 0));
-sum(a^i * x^i / i, i, 1, inf)$

/*
  A particular example of a log expansion that didn't work when you
  only allowed contents that SMONO accepted
*/
niceindices(powerseries(log(1-z*exp(-4)), z, 0));
-sum(exp(-4*i)*z^i/i, i, 1, inf)$

(kill(all), 0);
0$