HP Forums
Classic Fourier Series - Printable Version

+- HP Forums (https://www.hpmuseum.org/forum)
+-- Forum: HP Calculators (and very old HP Computers) (/forum-3.html)
+--- Forum: HP Prime (/forum-5.html)
+--- Thread: Classic Fourier Series (/thread-2946.html)

Pages: 1 2


RE: Classic Fourier Series - salvomic - 02-01-2015 05:34 PM

(02-01-2015 05:12 PM)Snorre Wrote:  Hi,

another approach:
...
This doesn't check types, but number of args, so usage is either fourier(expr,var,k) or fourier(func,k).

great!
Very "C" like Smile
I'll use this approach, then...
What the meaning of zip() function, please?


RE: Classic Fourier Series - Terje Vallestad - 02-01-2015 05:48 PM

(02-01-2015 05:34 PM)salvomic Wrote:  What the meaning of zip() function, please?

You could check the on calculator help

Code:


Syntax: 
zip(‘Function’, List1, List2, Default) or 
zip(‘Function’, Vector1, Vector2, Default) 

Applies a bivariate function to the elements of two lists or vectors 
and returns the results in a vector. Without the default value the 
length of the vector is the minimum of the lengths of the two lists; 
with the default value, the shorter list is padded with the default value. 

Example: 
zip('+',[a,b,c,d], [1,2,3,4]) ➔ [a+1,b+2,c+3,d+4] 
zip(sum,[a,b,c,d], [1,2,3,4]) ➔ [a+1,b+2,c+3,d+4]

Cheers, Terje


RE: Classic Fourier Series - salvomic - 02-01-2015 05:55 PM

(02-01-2015 05:48 PM)Terje Vallestad Wrote:  You could check the on calculator help

Cheers, Terje

yes, Terje, thank you!

In this case it "unapply" the name of the variable... ok

cheers


RE: Classic Fourier Series - Snorre - 02-01-2015 06:13 PM

Hi,

what the help doesn't mention is that zip doesn't work only on lists/vectors but also on a bivariate function and two scalars.
So, zip('+',2,3) gives 5.

unapply turns an expression into a function (see on-calc help):
unapply(expr,var1,...,varN) returns a function (var1,...,varN)->expr.

In fact the aim was something like "unapply(expr,var)", but not with "var" itself being the parameter but its value (another variable, e.g. "x").
That is "var:=x; unapply(expr,var)" will return "(var)->expr" -- not the desired "(x)->expr".
So, the zip construction evaluates "var" first before unapplying.


RE: Classic Fourier Series - salvomic - 02-01-2015 06:16 PM

just a powerful command!
I didn't know it first...

thanks a lot.


RE: Classic Fourier Series - salvomic - 02-01-2015 07:06 PM

(02-01-2015 05:12 PM)Snorre Wrote:  Hi,

another approach:
...

hi Snorre,
I'm almost ready to put a very better program, melting yours and mine, very short and powerful...

But I would have use "choose" for input to choose between two intervals for calculus (from 0 to 2PI or from -pi to pi), as the results seem to be different (they aren't but are correlated to those intervals)...
However I get "Error: invalid input": is it not possible to use "CHOOSE" with a #cas program? :-(

please, tell me...


RE: Classic Fourier Series - Snorre - 02-01-2015 08:37 PM

Hello Salvo,

you're right. In general, changing the integration interval is like shifting the time function, which should result in different phase information only (the magnitudes shall stay the same).
But that holds only for periodic functions (a basic assumption of fourier transformations). If you transform f(t):=t² in -pi..pi, you're assuming f is an endless repetition of the cup-like part pi²..0..pi² (in ASCII-art: ...uuuu...), if you do it on 0..2pi you're assuming f is an endless repetition of the raising 0..pi²..4pi² chunk (in ASCII-art: ...////...) -- these are two different time functions.

You could put your choose box in a non-exported (private) PPL-function within the same program and call it like <programname>.<funcname>:
Code:
ChooseInterval()
BEGIN
  LOCAL choice;
  CHOOSE(choice,...);
  RETURN choice;
END;

#cas
fourcoeff(...):=
BEGIN
  ...
  IF MYFOURIERPROG.ChooseInterval()=1 THEN
   ak:=...-pi..pi...
  ELSE
   ak:=...0..2*pi...
  END;
  ...
END;
#end



RE: Classic Fourier Series - salvomic - 02-01-2015 09:14 PM

(02-01-2015 08:37 PM)Snorre Wrote:  Hello Salvo,

you're right. ...
You could put your choose box in a non-exported (private) PPL-function within the same program and call it like <programname>.<funcname>:
...

ok!
I'm trying this code:
Code:

ChooseInterval()
BEGIN
  LOCAL choice;
  CHOOSE(choice,"Intervallo","from -pi to pi","from 0 to pi");
  RETURN choice;
END;


#cas
fourcoeff(args):=
// Coefficienti di fourier formula normale
// input funzione fourcoeff(func, k) o espressione funcoeff(expr, var, k)
BEGIN
local argv,argc,f,k;
local ak, bk, a0, a1, b1;
argv:=[args];
argc:=size(argv);
f := argv(1);
k := argv(argc);
IF argc=3 THEN f:=zip('unapply', f, argv(2)); END;
ak:=(int(f(t)*cos(k*t),t,-pi,pi))/pi;
bk:=(int(f(t)*sin(k*t),t,-pi,pi))/pi;
a0:=(int(f(t),t,0,2*PI))/(2*PI);
a1:=(int(f(t)*cos(k*t),t,0,2*PI))/PI;
b1:=(int(f(t)*sin(k*t),t,0,2*PI))/PI;
IF FourCoeff.ChooseInterval()=1 THEN 
return  {ak, bk}; ELSE  
return {a0, a1, b1};
END;

END;
#end

but it doesn't execute any Choice, always give a0, a1, b1, the last option (ELSE)...
The program name here is FourCoeff, its function fourcoeff(args)

Can you help me to find the last error, please?
For the rest it should be ok...


RE: Classic Fourier Series - Snorre - 02-01-2015 09:31 PM

Sorry, my fault -- didn't test it.
Try EXPR("FourCoeff.ChooseInterval()") instead of FourCoeff.ChooseInterval().


RE: Classic Fourier Series - salvomic - 02-01-2015 09:47 PM

(02-01-2015 09:31 PM)Snorre Wrote:  Sorry, my fault -- didn't test it.
Try EXPR("FourCoeff.ChooseInterval()") instead of FourCoeff.ChooseInterval().

yes!
it's ok. The choose box is very elegant also.
Works also with the piecewise function and (with some warnings) also with |sin(t)|
I've now a doubt (I'm aging, hi):
the correct formula for a0 and interval -π..π is divided by PI or by 2*PI? In some books of mine I find one and in others the other form...

And finally we could also include in this program your routine for cx (exponential form coefficient)...
What do you think?

Salvo


RE: Classic Fourier Series - Snorre - 02-01-2015 10:19 PM

Hello Salvo,

I think it's a matter of taste, but I do prefer the complex coefficients, because you see (ak,bk) directly (especially if you choose (a,b) format for complex numbers instead of a+b*i) and it's so easy to get the magnitude (abs) and phase (arg), which are in practice more interesting than sin/cos-parts.

I do not know, how a0 is exactly defined. But since it should be the mean (DC-coefficient) I'd divide the integral by its width 2*pi.

Greetings


RE: Classic Fourier Series - salvomic - 02-01-2015 10:33 PM

(02-01-2015 10:19 PM)Snorre Wrote:  I think it's a matter of taste, but I do prefer the complex coefficients, because you see (ak,bk) directly ...

you are right, the complex coefficient are preferable...

I'll think about make a program "all in one" or let two separate functions...

Thank a lot for the effort, very appreciated!

Greetings!

salvo


RE: Classic Fourier Series - Snorre - 02-01-2015 10:39 PM

(02-01-2015 10:33 PM)salvomic Wrote:  you are right, the complex coefficient are preferable...

No, no! Do it the way you like it. It's also easy to get the abs and arg of a [ak,bk]-vector.
That's the fun part of Prime: make it to your calculator.


RE: Classic Fourier Series - salvomic - 02-01-2015 11:00 PM

(02-01-2015 10:39 PM)Snorre Wrote:  
(02-01-2015 10:33 PM)salvomic Wrote:  you are right, the complex coefficient are preferable...

No, no! Do it the way you like it. It's also easy to get the abs and arg of a [ak,bk]-vector.
That's the fun part of Prime: make it to your calculator.

ok Smile
yes, it's mazing the Prime!

Salvo


RE: Classic Fourier Series - salvomic - 02-01-2015 11:24 PM

FourCoeff Version "all in one":
Input something like function or expression (with variable) and k:
g(t) -> "g, k", g(x) -> "g, x, k", "t^2, k", "x^2, x, k"... where k = (0), 1, 2, ...
It calculate the Fourier coefficient (trigonometric and exponential).
I hope the formulas be good, please control...

The output is sure "wild", it must be presented more clean, sorry...
My idea was to print the letter and the interval, but doing so the row is sure too long...
Any help appreciated.

Code:

ChooseInterval()
BEGIN
  LOCAL choice;
  CHOOSE(choice,"Interval", "from 0 to 2pi", "from -pi to pi");
  RETURN choice;
END;

#cas
fourcoeff(args):=

BEGIN
local argv,argc,f,k;
local ak, bk, a0,ck;
argv:=[args];
argc:=size(argv);
f := argv(1);
k := argv(argc);
IF argc=3 THEN f:=zip('unapply', f, argv(2)); END;

IF EXPR(" FourCoeff.ChooseInterval()")=1 THEN 
a0:=(int(f(t),t,0,2*PI))/(2*PI);
ak:=(int(f(t)*cos(k*t),t,0,2*PI))/PI;
bk:=(int(f(t)*sin(k*t),t,0,2*PI))/PI;
ck:=( int(f(t)*e^(-i*k*t),t0,pi))/pi;
return "0..2pi a0", a0, "a,b", {ak, bk}, "c", ck; ELSE
a0:=(int(f(t),t,0,pi))/(2*pi);
ak:=(int(f(t)*cos(k*t),t,-pi,pi))/pi;
bk:=(int(f(t)*sin(k*t),t,-pi,pi))/pi;
ck:=( int(f(t)*e^(-i*k*t),t,-pi,pi))/(2*pi);
return "-pi..pi a0", a0, "a,b", {ak, bk}, "c",ck;
END;

END;
#end


Everyone can adapt it at his/hers needs Smile

Salvo M.


RE: Classic Fourier Series - salvomic - 02-02-2015 10:59 AM

there was an error in a formula...
Output like vector, a little better than the first one...
(Please tell me the true syntax of Return command: how to do to have two lines, ho to avoid "" and have "labels", without using ' ' (that evaluate expression)...

Code:

ChooseInterval()
BEGIN
LOCAL choice;
CHOOSE(choice,"Interval","From 0 to 2π","From −π to π");
RETURN choice;
END;

#cas
fourcoeff(args):=
// Coefficienti di Fourier formula normale,  by Salvo Micciché v 1.0
// input funzione fourcoeff(func, k) o espressione fourcoeff(expr, var, k)
BEGIN
local argv,argc,f,k;
local ak, bk, a0,ck;
argv:=[args];
argc:=size(argv);
f := argv(1);
k := argv(argc);
IF argc=3 THEN f:=zip('unapply', f, argv(2)); END;

IF EXPR(" FourCoeff.ChooseInterval()")=1 THEN 
a0:=(int(f(t),t,0,2*PI))/(2*PI);
ak:=(int(f(t)*cos(k*t),t,0,2*PI))/PI;
bk:=(int(f(t)*sin(k*t),t,0,2*PI))/PI;
ck:=( int(f(t)*e^(-i*k*t),t,0,2*pi))/(2*pi);
RETURN {"[0,2π] a₀ aₙ bₙ", a0,ak,bk, "cₙ", ck}; ELSE
a0:=(int(f(t),t,-pi,pi))/(2*pi);
ak:=(int(f(t)*cos(k*t),t,-pi,pi))/pi;
bk:=(int(f(t)*sin(k*t),t,-pi,pi))/pi;
ck:=( int(f(t)*e^(-i*k*t),t,-pi,pi))/(2*pi);
RETURN {"[-π,π] a₀ aₙ bₙ", a0,ak,bk, "cₙ", ck};
END;

END;
#end



RE: Classic Fourier Series - salvomic - 02-03-2015 08:06 PM

(02-01-2015 05:12 PM)Snorre Wrote:  another approach:
Code:
#cas
...
  f:=argv(1);
  k:=argv(argc);
  IF argc=3 THEN f:=zip('unapply',f,argv(2)); END;
 ...
#end
This doesn't check types, but number of args, so usage is either fourier(expr,var,k) or fourier(func,k).
I like this approach!

please, Snorre, help with this code (see thread with Han in http://www.hpmuseum.org/forum/thread-2992.html...
I would like calculate curvilinear integral with input a function (x,y,z), a parametric curve [r(t), r(t), r(t)], low bound, high bound; then I would write also a program for line integral (vectorial function, so: [x,y,z] fun, [t,t,t] param, l, h)...
I need some controls with the expression or function (for now if I put f and not f(x) Prime reset, as we now), for the parametric vector [t,...,...] e mostly for the variables in those two: they could be 2 or 3...
Any help?

With expression in x,y,z, vector [t...],l,h the function works well, the only control now is that there be 4 parameters...

Code:

#cas
intcur(args):=
BEGIN
local a, b, f, r, dr, ft;

argv:=[args];
argc:=size(argv);
IF argc !=4 THEN
return "Input: scalar func, [param curve t] ,low, high"; 
 ELSE
f:=argv(1);
r:=argv(2);
a:=argv(3);
b:=argv(4);
dr:=diff(r,t);
ft:=subst(f,[x,y,z]=r);
return int(dot(ft,l2norm(dr)),t,a,b);
END;

END;
#end
I hope don't bore you long time Wink

P.S. we could also continue in the other thread, if you want, as here we are a bit off topic Smile


RE: Classic Fourier Series - salvomic - 04-11-2015 05:35 AM

New version

Use, as always:fourcoeff(func, k) or fourcoeff(func, var, k), es. fourcoeff(COS(t/2), t, 1) of fourcoeff(x^2, 2)...

This now permits a choose from 3 interval: [0, 2PI], [-PI, PI], [other], where "other" gives the opportunity to input a value for a parameter T to get an interval like [-T/2, T/2]; es. input 2 to have [-1, 1], for a non trigonometric function of a function...
The program return then a_0, a_n, b_n (trigonometric form), and c_n (exponential form) of Fourier's Series for a given number (int: n -> 1, 2, 3...)

Code:

ChooseInterval()
BEGIN
LOCAL choice;
CHOOSE(choice,"Interval","From 0 to 2π","From −π to π", "Other");
RETURN choice;
END;

inputT()
// input routine for choice 3
BEGIN
INPUT(T, "Interval", "Period T",  "Input T for [-T/2, T/2]", 2);
RETURN T;
END;

#cas
fourcoeff(args):=
// Coefficienti di Fourier formula normale,  by Salvo Micciché v 1.0
// input funzione fourcoeff(func, k) o espressione fourcoeff(expr, var, k)
BEGIN
local argv,argc,f,k;
local ak, bk, a0,ck;
local scelta;
argv:=[args];
argc:=size(argv);
f := argv(1);
k := argv(argc);
IF argc=3 THEN f:=zip('unapply', f, argv(2)); END;

scelta:= EXPR(" FourCoeff.ChooseInterval()");

CASE
IF scelta=1 THEN 
a0:=(int(f(t),t,0,2*PI))/(PI);
ak:=(int(f(t)*cos(k*t),t,0,2*PI))/PI;
bk:=(int(f(t)*sin(k*t),t,0,2*PI))/PI;
ck:=( int(f(t)*e^(-i*k*t),t,0,2*pi))/(pi);
RETURN {"[0,2π] a₀ aₙ bₙ", a0,ak,bk, "cₙ", ck}; 
END;

IF scelta=2 THEN
a0:=(int(f(t),t,-pi,pi))/(pi);
ak:=(int(f(t)*cos(k*t),t,-pi,pi))/pi;
bk:=(int(f(t)*sin(k*t),t,-pi,pi))/pi;
ck:=( int(f(t)*e^(-i*k*t),t,-pi,pi))/(pi);
RETURN {"[-π,π] a₀ aₙ bₙ", a0,ak,bk, "cₙ", ck}; 
END;

IF scelta=3 THEN 
EXPR("FourCoeff.inputT()");
// input T for interval [-T/2, T/2] es. 2pi -> [-pi, pi], 2 -> [-1,1] ...
a0:= exact( (int(f(t),t,-(T/2),T/2))*2/T );
ak:=exact( (int(f(t)*cos((2*PI*k/T)*t),t, -T/2, T/2))*2/T);
bk:=exact( (int(f(t)*sin((2*PI*k/T)*t),t,-T/2,T/2))*2/T );
ck:=exact( ( int(f(t)*e^(-i*k*t),t, -(T/2),T/2))*2/T );
RETURN {"[t₀,T] a₀ aₙ bₙ", a0,ak,bk, "cₙ", ck}; 
END;

DEFAULT RETURN("Choose periodicity interval");
END; // case

END;
#end

(in case of error, substitute the underscript in RETURN {"[t₀,T] a₀ aₙ bₙ", a0,ak,bk, "cₙ", ck} with the _n ...)

Salvo


RE: Classic Fourier Series - StephenG1CMZ - 10-09-2015 09:37 PM

Salvomic, you were asking how to Return two lines.
Does this help:
"ABC" + CHAR(10) + "Def"
Gives a string over two lines.
RETURN "A" + CHAR(10) + "B"
returns a two-line string.

CHAR(10) is an ASCII linefeed.


RE: Classic Fourier Series - salvomic - 10-10-2015 07:38 AM

(10-09-2015 09:37 PM)StephenG1CMZ Wrote:  Salvomic, you were asking how to Return two lines.
Does this help:
"ABC" + CHAR(10) + "Def"
Gives a string over two lines.
RETURN "A" + CHAR(10) + "B"
returns a two-line string.

CHAR(10) is an ASCII linefeed.

thank you a lot, Stephen,
I'll try it soon!

Salvo