-
Notifications
You must be signed in to change notification settings - Fork 3
/
Documentation-pdefourier.wxm
3659 lines (2353 loc) · 87.9 KB
/
Documentation-pdefourier.wxm
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
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* [wxMaxima batch file version 1] [ DO NOT EDIT BY HAND! ]*/
/* [ Created with wxMaxima version 19.07.0 ] */
/* [wxMaxima: title start ]
pdefourier: A Maxima package to study Fourier series
and partial differential equations
[wxMaxima: title end ] */
/* [wxMaxima: comment start ]
José Antonio Vallejo
email: jvallejo@fc.uaslp.mx
URL hhtp://galia.fc.uaslp.mx/~jvallejo
Emmanuel Roque
email: earoque@math.cinvestav.mx
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
Abstract: Fourier Analysis provides a set of techniques for solving partial differential
equations (PDEs) in several contexts: bounded and unbounded domains, with mixed
conditions, purely initial conditions, etc. In the bounded domain case, the basic idea
is to apply the separation of variables method (in the unbounded case, it is the Fourier
transform), which leads to a well-defined algorithm for developing the solution in a
Fourier series. Precisely, the fact that there exists an algorithm for computing the solution
makes this kind of problem tractable with a Computer Algebra System (CAS), and here
we introduce a Maxima package (called 'fourier') to solve it. It is still work in
progress, and lots of things remain to be implemented. But in its actual stage it is already
usable and useful in teaching some university-level courses, so here it is.
[wxMaxima: comment end ] */
/* [wxMaxima: section start ]
Preliminaries
[wxMaxima: section end ] */
/* [wxMaxima: comment start ]
First of all, we load the package (assuming that the file 'pdefourier.mac' has been
copied to /usr/share/maxima/5.42.1/share/contrib or something similar, depending
on the version and the operating system. In Windows probably it will be the location
c:\Program files (x86)\Maxima-sbcl-5.42.1/share/maxima/5.42.1/share/contrib).
Another possibility is to keep a copy in the working directory.
It automatically calls other packages (such as draw). In the command below, type
"nul" instead of "/dev/null" when working on a Windows machine:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
kill(all);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
with_stdout("/dev/null",load("../pdefourier.mac"))$
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
This is just to avoid some annoying warnings...
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
ratprint:false$
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
The following rules will be useful later on, when simplifying the expression of the Fourier
coefficients for some functions:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
defrule(rul1,sin((%pi*n)/2),(-1)^(floor(n/2))*(1 - (-1)^n)/2);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
defrule(rul2,cos((%pi*n)/2),(-1)^(floor(n/2))*(1 + (-1)^n)/2);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Indeed, notice that
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
makelist((-1)^(floor(n/2))*(1 - (-1)^n)/2,n,0,9);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
and
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
makelist((-1)^(floor(n/2))*(1 + (-1)^n)/2,n,0,9);
/* [wxMaxima: input end ] */
/* [wxMaxima: section start ]
The functions 'paritycheck' and 'pw2list'
[wxMaxima: section end ] */
/* [wxMaxima: comment start ]
The package contains 'paritycheck', a command to determine the parity of expressions.
When the input expression is a piecewise-defined function, it is compulsory that it be
written either as
if x>=a_0 and x<=a_1 then expr1 elseif ... elseif x>a_n and x<=a_{n+1} then expr_{n+1}
(in the case of bounded domains) or as
if x<=a_0 then expr0 elseif x>a0 and x<=a1 then expr1 ... elseif x>=a_n then exprn
(in the unbounded case).
Important notes:
-In all cases it is expected that a_i<a_{i+1}. Writing (x<=7 and x>=6) instead of
(x>=6 and x<=7) won't work for some technical reasons.
-Use of 'else' is unsupported, the expression following 'else' is ignored! Use 'elseif' instead.
-The logical operator "or" is currently unsupported, will be treated as 'and'.
-The 'paritycheck' function will not check whether the intervals are disjoint or not.
This 'paritycheck' function is essential, as it simplifies the computation of the Fourier
coefficients when there are symmetries.
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
Let us define several functions that will be used later as examples, and test the
'paritycheck' command on them.
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
absolute(x):=if (x<=0) then -x elseif (x>0) then x$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(absolute(x),[x,-1,1],[ylabel,"absolute value"]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(absolute(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
heaviside(x):=if (x<0) then 0 elseif (0<=x) then 1$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(heaviside(x),[x,-1,1],[y,-0.1,1.1],[ylabel,"step function"]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(heaviside(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
square(x):=if (x<-%pi) then 0 elseif (-%pi<=x and x<=%pi) then 1 elseif (x>%pi) then 0$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(square(x),[x,-4,4],[y,-0.1,1.1],[ylabel,"square pulse"]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(square(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
The square pulse with compact support:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
square0(x):=if (-2<=x and x<-1) then 0 elseif (-1<=x and x<=1) then 1 elseif (1<x and x<=2) then 0$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(square0(x),[x,-2,2],[y,-0.1,1.1],[ylabel,"square pulse"]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(square0(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
More complicated functions. Notice that some have compact support while others do not.
We will use them later for illustration purposes.
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
f(x):=if (x<-3) then 0 elseif (-3<=x and x<=-2) then 1 elseif (-2<x and x<=-1) then 0
elseif (-1<x and x<=1) then -x elseif (1<x and x<=2) then 0
elseif (2<x and x<3) then -1 elseif (x>=3) then 0$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(f(x),[x,-4,4],[y,-1.1,1.1]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(f(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
g(x):=if (x<-1/2) then x+1
elseif (x>=-1/2 and x<-1/4) then 0
elseif (x>=-1/4 and x<1/4) then abs(x)
elseif (x>=1/4 and x<1/2) then 0
elseif (x>=1/2) then 1-x$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(g(x),[x,-2,2]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(g(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
h(x):=if (x<-3) then 1 elseif (-3<=x and x<=-2) then 0 elseif (-2<x and x<-1) then 1
elseif (-1<=x and x<=0) then 0 elseif (0<x and x<1) then 1 elseif (1<=x and x<=2) then 0
elseif (2<x and x<3) then 1 elseif (x>=3) then 0$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(h(x),[x,-4,4],[y,-0.1,1.1]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(h(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
k(x):=if (x<-3) then 1 elseif (-3<=x and x<=-2) then 0 elseif (-2<x and x<-1) then 1
elseif (-1<=x and x<=1) then 0.5 elseif (1<x and x<=2) then 1
elseif (2<x and x<3) then 0 elseif (x>=3) then 1$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(k(x),[x,-4,4],[y,-0.1,1.1]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(k(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
u(x):=if (x>=-1 and x<-1/2) then -1-x
elseif (x>=-1/2 and x<1/2) then x^3
elseif (x>=1/2 and x<=1) then 1-x$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(u(x),[x,-1,1]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(u(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
v(x):=if (-%pi<=x and x<0) then x^2 elseif (0<=x and x<=%pi) then sin(3*x)$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d(v(x),[x,-%pi,%pi],[ylabel,"v(x)"]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(v(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
For the sake of completeness, let us give some examples of expressions not piecewise-defined.
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
paritycheck(sin(4*theta),theta);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(x^2,x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
paritycheck(x^2-x+1,x);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Internally, when the input expression is piecewise-defined, 'paritycheck' calls another function,
'pw2list', to extract the pieces and work with a list representation of the expression.
Thus, the expression
if x>=a_0 and x<=a_1 then expr1 elseif x>a_1 and x<= a_2 then expr2 ... elseif x>a_n and x<=a_{n+1} then expr_{n+1}
would translate to
[[[a_0,a_1],expr1],[[a_1,a_2],expr2],...,[[a_n,a_{n+1}],expr_{n+1}]]
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
Let's see how it works with h(x) and v(x) as examples:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
fundef(h);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
pw2list(h(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fundef(v);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
pw2list(v(x),x);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Working with piecewise functions using this approach can be very useful for many different
purposes, such as computing their integral, as we will see later on this document.
[wxMaxima: comment end ] */
/* [wxMaxima: section start ]
The Fourier coefficients
[wxMaxima: section end ] */
/* [wxMaxima: comment start ]
The package 'pdefourier' provides a function to compute the Fourier coefficients of a
piecewise defined function. It uses 'paritycheck' to simplify the calculations (if the
function is even, then all the coefficients b_n=0, etc.) The output has the format of a
list
[[a_0/2,a_n,b_n],[singular values]]
where a_n are the Fourier cosine coefficients and b_n the Fourier sine coefficients.
The singular values list, might be empty or not, depending on the input expression. For
example, if f(x)=sin(3*x)+cos(7*x) in the interval [-%pi,%pi], then, a_n=0 except when n=7,
and b_n=0 except when n=3. When such special cases appear, the singular values list will
contain the corresponding values of n and a_n, b_n, as they must be computed separately.
The function fouriercoeff currently searches for singular values that appear in trigonometric
expressions involving sines and cosines whose arguments are integer multiples of the
fundamental frequencies, and in the product of polynomials with sines and cosines with such
arguments.
Notice that the computation of Fourier coefficients can be done for any interval [a,b], with the
only restriction that it must be bounded. The syntax is as follows:
fouriercoeff(expression, variable, p), where p=(b-a)/2.
For example, if a function is defined in an interval [-L,L], then p=L. By default, if an expression
is not piecewise-defined, 'fouriercoeff' assumes that it is defined in [-%pi,%pi].
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
First, a couple of examples of non piecewise-defined expressions:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
fouriercoeff(sin(3*x)+cos(7*x),x,%pi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(x^2+1,x,1);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Now let's see how it works with piecewise defined expressions
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
absolute0(x):=if ( x>=-1 and x<=0) then -x elseif (x>0 and x<=1) then x$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(absolute0(x),x,1);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
heaviside0(x):=if ( x>=-1 and x<0 ) then 0 elseif (0<=x and x<=1) then 1$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(heaviside0(x),x,1);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
For some reason, Maxima does not simplify factors like sin(n*%pi/2) even if n is declared
to be an integer, but this is a minor issue that can be easily corrected 'by hand', using
the rules defined above. Other rules can be defined by the user, following the same pattern.
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
fouriercoeff(square0(x),x,2);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
apply1(%,rul1);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
f0(x):=if (x>=-4 and x<-3 ) then 0 elseif (-3<=x and x<=-2) then 1 elseif (-2<x and x<-1) then 0
elseif (-1<=x and x<=1) then -x elseif (1<=x and x<=2) then 0
elseif (2<x and x<3) then -1 elseif (x>=3 and x<=4) then 0$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(f0(x),x,4);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
apply1(%,rul2);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
g0(x):=if (x>=-1 and x<-1/2 ) then x+1
elseif (x>=-1/2 and x<-1/4) then 0
elseif (x>=-1/4 and x<=0) then -x
elseif (x>=0 and x<=1/4) then x
elseif (x>=1/4 and x<1/2) then 0
elseif (x>=1/2 and x<=1) then 1-x$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(g0(x),x,1);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
apply1(%,rul1,rul2);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
h0(x):=if (x>=-4 and x<-3 ) then 1 elseif (-3<=x and x<=-2) then 0 elseif (-2<x and x<-1) then 1
elseif (-1<=x and x<=0) then 0 elseif (0<x and x<1) then 1 elseif (1<=x and x<=2) then 0
elseif (2<x and x<3) then 1 elseif (x>=3 and x<=4) then 0$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(h0(x),x,4);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
apply1(%,rul1,rul2);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
k0(x):=if (x>=-4 and x<-3) then 1 elseif (-3<=x and x<=-2) then 0 elseif (-2<x and x<-1) then 1
elseif (-1<=x and x<=1) then 0.5 elseif (1<=x and x<=2) then 1
elseif (2<x and x<3) then 0 elseif (x>=3 and x<=4) then 1$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(k0(x),x,4);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
apply1(%,rul1,rul2);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(u(x),x,1);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
apply1(%,rul1,rul2);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Further simplification can be achieved by separating even and odd-order coefficients. Taking as
an example the last expression, we start by declaring:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
declare(s,integer)$
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
The even-order coeffcients b_2s:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
subst(n=2*s,%th(2));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
syntactic_factor(%);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
And the odd-order ones:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
subst(n=2*s-1,%th(4));
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
syntactic_factor(%);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Another example of this kind of simplification
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
fouriercoeff(v(x),x,%pi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
subst(n=2*s,%);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
subst(n=2*s-1,%th(2));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Once we are finished with the auxiliary variable s, we can unbind it
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
remove(s,integer);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Next, we consider examples with arbitrary intervals (not necessarily of the form [-L,L]).
When working with "symbolic" intervals, it is important to declare its endpoints
as constants, otherwise, 'fouriercoeff' might not work as expected or return an error.
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
declare(L,constant);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
assume(L>0);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
f1(x):=if (0<=x and x<L) then A elseif (L<=x and x<=2*L) then 0$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(f1(x),x,L);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
forget(L>0);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
remove(L,constant);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Here is another example:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
f2(x):=if (0<=x and x<=1) then x elseif (1<x and x<=2) then 1 elseif (2<x and x<=3) then 3-x$
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Remember that in an interval [a,b], the value of p is (b-a)/2!
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
syntactic_factor(fouriercoeff(f2(x),x,3/2));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
When a#0 or a#-b, the function must be defined in the 'if ... elseif ...' format, as in the
next example:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
tst(x):= if (3<=x and x<=4) then x^2$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(tst(x),x,1/2);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Notice that in this case, the trigonometric factors will have the form cos(2n %pi x) and
sin(2n %pi x).
[wxMaxima: comment end ] */
/* [wxMaxima: section start ]
The Fourier series
[wxMaxima: section end ] */
/* [wxMaxima: comment start ]
There are two possibilities for computing the Fourier series of a functio in 'pdefourier'.
For those cases where we have already computed some Fourier coefficients with
'fouriercoeff', there is the function 'fouriercoeff_expand'. There is also the command
'fourier_series', which works on user-defined functions or expressions, and admits a
parameter 'N' that can take any integer value N>=1 and determines the order of the
truncated Fourier series. If N=inf, then the function will output the whole Fourier series
in symbolic form, as an infinite sum.
[wxMaxima: comment end ] */
/* [wxMaxima: comment start ]
First, an example using 'fouriercoeff_expand', to see how it works:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
fouriercoeff(f2(x),x,3/2);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff_expand(%,x,3/2,inf);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
In the following examples, we construct several Fourier series and draw them side
by side with the original functions (original functions in blue, Fourier approximations in red).
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
series1:fourier_series(absolute0(x),x,1,10);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([absolute0(x),series1],[x,-1,1],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
The complete Fourier series for this example can be obtained as follows:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
fourier_series(absolute0(x),x,1,inf);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
declare(s,integer)$
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
In this particular case, only the odd-order coefficients survive. However, with the direct
substitution n=2s-1, the labels of the terms in the series become a mess. This is something
to be corrected in future versions.
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
subst(n=2*s-1,%th(2));
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
This is the same result obtained in Stewart's Calculus, see page 7 in
http://www.stewartcalculus.com/data/CALCULUS%20Concepts%20and%20Contexts/upfiles/3c3-FourierSeries_Stu.pdf
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
remove(s,integer)$
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Let us see more examples of Fourier series, compared to the function they come from.
The Fourier series in some examples are long and ugly, so we suppress the output with
the aid of the dollar sign '$' at the end of the command (surely you have already noticed
its use earlier in the document):
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
series2:fourier_series(heaviside0(x),x,1,10);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([heaviside0(x),series2],[x,-1,1],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
series3:fourier_series(square0(x),x,2,10);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([square0(x),series3],[x,-2,2],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
series4:fourier_series(f0(x),x,4,15)$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([f0(x),series4],[x,-4,4],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
series5:fourier_series(g0(x),x,1,15)$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([g0(x),series5],[x,-1,1],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
series6:fourier_series(h0(x),x,4,15);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([h0(x),series6],[x,-4,4],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
series7:fourier_series(k0(x),x,4,15)$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([k0(x),series7],[x,-4,4],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
series8:fourier_series(u(x),x,1,15)$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([u(x),series8],[x,-1,1],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
series9:fourier_series(v(x),x,%pi,15)$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([v(x),series9],[x,-%pi,%pi],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
The case of arbitrary intervals (not necessarily of the form [-L,L]):
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
series11:fourier_series(f2(x),x,3/2,3);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([f2(x),series11],[x,0,3],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Here is (half of) Exercise 8.16 in D. Richards "Advanced Mathematical Methods with Maple":
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
fouriercoeff(x^2,x,%pi);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
Now, let's do an example that shows how the package handles the series of functions
with singular values in their coefficients.
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
expr:x^2*cos(4*x);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(expr,x,%pi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fourier_series(expr,x,%pi,inf);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
As we can see, 'fourier_series' reads the list of singular values and separates those terms from the series.
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
series12:fourier_series(expr,x,%pi,12)$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([expr,series12],[x,-%pi,%pi],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
kill(expr)$
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
An example from the Maxima list:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
ffo(t):=if (-%pi<=t and t<=0) then 3*t+5 elseif (0<t and t<=%pi) then 2*%pi-3*t-9;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
fouriercoeff(ffo(t),t,%pi);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
seri6:fourier_series(ffo(t),t,%pi,6);
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([ffo(t),seri6],[t,-%pi,%pi],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: comment start ]
This example comes from a web
page whose URL we don't remember. If you are the owner of that page and are reading this,
please let us know to get proper recognition:
[wxMaxima: comment end ] */
/* [wxMaxima: input start ] */
d(x):=if ( x>=-%pi and x<=0 ) then 1 elseif (0<x and x<=1/2) then 2 elseif (1/2<x and x<=%pi) then 1/x;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
series10:fourier_series(d(x),x,%pi,15)$
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
expand(series10),numer;
/* [wxMaxima: input end ] */
/* [wxMaxima: input start ] */
wxplot2d([d(x),%],[x,-%pi,%pi],[y,0.2,2.1],[legend,false]);
/* [wxMaxima: input end ] */
/* [wxMaxima: section start ]
Animations
[wxMaxima: section end ] */
/* [wxMaxima: comment start ]
Let us see the approximation process dynamically (this requires wxMaxima):
[wxMaxima: comment end ] */