PWfunctions

A PWfunction is a point-wise defined function. It is one way of representing data found in a file. It is essentially a table that associates to some points θi a value fi. The BEP program start with converting such a function into a Fourier series, which is completely different way of representing the data.

In the case of continuous-time systems, the transfer function F depends on a complex variable s, is generally analytic in the half-plane Re(s)>0 and data are given for s on the imaginary axis, s=i*ω. In the case of discrete-time systems the transfer function F depends on a complex variable z, is analytic in the unit disk |z|<1 and data are given for z on the unit circle, z=exp(i*θ).

(#:pw:reorder F ) (Lisp function)

This changes the order of items, by increasing θ

(1) x3:= #Pw 4 10 1 2 3 3 4 7 5 6 2 7 8;

(1)  <pw function: 10 = 1 + 2 %i, 3 = 3 + 4 %i, 7 = 5 + 6 %i, 2 = 7 + 8 %i>

(2) #:pw:reorder(x3);

(2)  <pw function: 2 = 7 + 8 %i, 3 = 3 + 4 %i, 7 = 5 + 6 %i, 10 = 1 + 2 %i>

(#:pw:get_theta F i) (Lisp function)

(#:pw:get_val F i) (Lisp function)

(#:pw:set_theta F i t) (Lisp function)

(#:pw:set_val F i x) (Lisp function)

These four functions can be used to get or set a value. The functions getcoef and setcoef can also be used to set a value.

[Endymion] (setq x #Pw 4 1 2 3 4 5 6 7 8 9 10 11 12)
#Pw 4 1 2 3 4 5 6 7 8 9 10 11 12 
[Endymion] (#:pw:get_theta x 0)
1
[Endymion] (#:pw:get_val x 0)
[3i+2]
[Endymion] (#:pw:set_val x 0 8)
8
[Endymion] (#:pw:set_theta x 0 7)
7
[Endymion] (getcoef x 3)
[12i+11]
[Endymion] (setcoef x 3 4)
4

You can consider a PWfunction as an array, so that X[i] is the same as getcoef(X,i). You can also consider it as an array with two indices: if the first index theta or omega then #:pw:get_theta is used, if it is value, then getcoef is used. In these cases, the second index is an integer. The index can also be assoc: in this case the second index is some θ and the value associated to this θ is returned. In all these cases, the value in the array can be modified. The first index can also be interpolate; in this case the value associated to this θ is returned, using linear interpolation if appropriate.

(2) x:= #Pw 4 1 2 3 4 5 6 7 8 9 10 11 12;

(2)  <pw function: 1 = 2 + 3 %i, 4 = 5 + 6 %i, 7 = 8 + 9 %i, 10 = 11 + 12 %i>

(3) x[0];

(3)                                2 + 3 %i

(4) x[0]:=#C(0,1);

(4)                                   %i

(6) x[theta,3];

(6)                                   10

(7) x[omega,3];

(7)                                   10

(8) x[value,3];

(8)                               11 + 12 %i

(9) x[assoc,10];

(9)                               11 + 12 %i

(10) x[assoc,10]:=14;

(10)                                  14

(11) x;

(11)      <pw function: 1 = %i, 4 = 5 + 6 %i, 7 = 8 + 9 %i, 10 = 14>

(12) x["interpolation",8];

(12)                               10 + 6 %i

(#:pw:fill_function f g) (Lisp function)

(#:pw:change_theta f h) (Lisp function)

Given a PW function f defined by pairs (xi,fi), and a function g, the first function replaces fi by g(xi) (this should be a complex number). The second function replaces xi by h(xi).

[Endymion] (setq x (#:pw:alloc_function 10 0 9))
#Pw 10 0 0 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0 
[Endymion] (#:pw:fill_function x (lambda (u)(+ 3 (* u #C(2 1)))))
#Pw 10 0 3 0 1 5 1 2 7 2 3 9 3 4 11 4 5 13 5 6 15 6 7 17 7 8 19 8 9 21 9 
[Endymion] (#:pw:change_theta x (lambda (u)(+ u 3)))
#Pw 10 3 3 0 4 5 1 5 7 2 6 9 3 7 11 4 8 13 5 9 15 6 10 17 7 11 19 8 12 21 9 
[Endymion] (#:pw:fill_function 'x 'ncons)
#:pw:fill_function : Not a pw function : x
[Endymion] (#:pw:fill_function x 5)
funcall : undefined function : 5
[Endymion] (#:pw:fill_function x 'car)
car : not a list : 3
[Endymion] (#:pw:fill_function x 'cons)
cons : wrong number of arguments : 1 this should be 2
[Endymion] (#:pw:fill_function x 'ncons)
#:pw:fill_function : not a real number : (3)
[Endymion] (#:pw:change_theta x 'ncons)
#:pw:change_theta : not a real number : (3)
[Endymion] (#:pw:change_theta x 'cons)
cons : wrong number of arguments : 1 this should be 2
[Endymion] (#:pw:change_theta x 'car)
car : not a list : 3
[Endymion] (#:pw:change_theta x '0)
funcall : undefined function : 0

Same example, in symbolic mode

(1) x:=#Pw 10 0 0 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0;


(1)  <pw function: 0 = 0, 1 = 0, 2 = 0, 3 = 0, 4 = 0, 5 = 0, 6 = 0, 7 = 0, 

8 = 0, 9 = 0>

(2) #:pw:fill_function(x,lambda(u, 3+u*#C(2,1)));


(2)  <pw function: 0 = 3, 1 = 5 + %i, 2 = 7 + 2 %i, 3 = 9 + 3 %i, 

4 = 11 + 4 %i, 5 = 13 + 5 %i, 6 = 15 + 6 %i, 7 = 17 + 7 %i, 8 = 19 + 8 %i, 

9 = 21 + 9 %i>

(3) #:pw:change_theta(x,lambda(u, u+3));

(3)  <pw function: 3 = 3, 4 = 5 + %i, 5 = 7 + 2 %i, 6 = 9 + 3 %i, 

7 = 11 + 4 %i, 8 = 13 + 5 %i, 9 = 15 + 6 %i, 10 = 17 + 7 %i, 11 = 19 + 8 %i, 

12 = 21 + 9 %i>

(#:pw:set_to_one f) (Lisp function)

This function takes as argument a PWfunction, and replaces the real and imaginary parts of the values by 1. The function can be be used as a dummy weight for splines. The effect is the same as (#:pw:fill_function f (lambda (u) #C(1 1)))

[Endymion] (#:pw:set_to_one (#:pw:alloc_function 4 0 3))
#Pw 4 0 1 1 1 1 1 2 1 1 3 1 1
[Endymion] (#:pw:set_to_one 'x)
#:pw:set_to_one : Not a pw function : x

(#:pw:shift_theta F t) (Lisp function)

sub_inf(F, v) (Symbolic function)

These two function take as arguments a PWfunction F and a real number t or complex number v. They add t to each θ or subtract v from each value. The example below shows how these functions could be written in Endymion.

(1) incr(x,y)::=buildq(x:=x+y)?;

(2) Shift_theta(f,t):= <<for i in 0...size(f)-1 do incr(f["theta",i], t), f >>;


(2)                       <FUNCTION: Shift_theta>

(3) Sub_inf(f,t):=  <<for i in 0...size(f)-1 do incr(f[i], -t), f >>;

(3)                         <FUNCTION: Sub_inf>

(4)  x:=#Pw 4 1 2 3 4 5 6 7 8 9 10 11 12;

(4) <pw function: 1 = 2 + 3 %i, 4 = 5 + 6 %i, 7 = 8 + 9 %i, 10 = 11 + 12 %i>

(5) #:pw:shift_theta(x,3);

(5) <pw function: 4 = 2 + 3 %i, 7 = 5 + 6 %i, 10 = 8 + 9 %i, 13 = 11 + 12 %i>

(6) Shift_theta(x,3);

(6) <pw function: 7 = 2 + 3 %i, 10 = 5 + 6 %i, 13 = 8 + 9 %i, 16 = 11 + 12 %i>

(7) #:pw:sub_inf(x,#C(2 3));

(7)  <pw function: 7 = 0, 10 = 3 + 3 %i, 13 = 6 + 6 %i, 16 = 9 + 9 %i>

(8) Sub_inf(x,#C(3, 3));

(8)  <pw function: 7 = - 3 - 3 %i, 10 = 0, 13 = 3 + 3 %i, 16 = 6 + 6 %i>

(#:pw:skip_unwanted F a b c) (Lisp function)

This function takes as argument a PW function. The assumption is that the points θi are in increasing order. Assume θj <= a < θj+1. In this case, all pairs (θi,fi) with i less than j are discarded. Moreover θj is replaced by a, and fj is obtained by linear interpolation. The same behavior is applied to the upper bound b. The last argument c is optional, it is ignored unless the value is 1 or 2. Here 1 means: truncate only the lower bound, and 2 means truncate only the upper bound.

[Endymion] (setq x6 (#:pw:alloc_function 5 1 5))
#Pw 5 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 
[Endymion] (defun ff(x) (+ (* x #C(2 1)) 3))
ff
[Endymion] (#:pw:fill_function x6 'ff)
#Pw 5 1 5 1 2 7 2 3 9 3 4 11 4 5 13 5 
[Endymion] (#:pw:skip_unwanted x6 1 5)
#Pw 5 1 5 1 2 7 2 3 9 3 4 11 4 5 13 5 
[Endymion] (#:pw:skip_unwanted x6 1.3 4.5)
#Pw 5 1.3 5.6 1.3 2 7 2 3 9 3 4 11 4 4.5 12 4.5 
[Endymion] (#:pw:skip_unwanted x6 1.4 4.5)
#Pw 5 1.4 5.8 1.4 2 7 2 3 9 3 4 11 4 4.5 12 4.5 
[Endymion] (#:pw:skip_unwanted x6 2.4 4.5)
#Pw 4 2.4 7.8 2.4 3 9 3 4 11 4 4.5 12 4.5 
[Endymion] (#:pw:skip_unwanted x6 2.4 3.5)
#Pw 3 2.4 7.8 2.4 3 9 3 3.5 10 3.5 
[Endymion] (#:pw:skip_unwanted x6 2.5 2.6 1)
#Pw 3 2.5 8 2.5 3 9 3 3.5 10 3.5 
[Endymion] (#:pw:skip_unwanted x6 2.6 3.4 2)
#Pw 3 2.5 8 2.5 3 9 3 3.4 9.8 3.4 
[Endymion] (#:pw:skip_unwanted x6 1.4 3.5)
#:pw:skip_unwanted : Lower bound too small : 1.4
[Endymion] (#:pw:skip_unwanted x6 10.4 3.5)
#:pw:skip_unwanted : Lower bound too large : 10.4
[Endymion] (#:pw:skip_unwanted x6 3. 1.4)
#:pw:skip_unwanted : Upper bound too small : 1.4
[Endymion] (#:pw:skip_unwanted x6 3. 10.4)
#:pw:skip_unwanted : Upper bound too large : 10.4
[Endymion] (#:pw:skip_unwanted x6 'x 3.5)
#:pw:skip_unwanted : not a real number : x
[Endymion] (#:pw:skip_unwanted x6  3.5 'c) 
#:pw:skip_unwanted : not a real number : c
[Endymion] (#:pw:skip_unwanted 'x6  3.5 4.2)
#:pw:skip_unwanted : Not a pw function : x6

(#:pw:make_symmetric F sw) (Lisp function)

This function takes as argument a PW function. The points θi are assumed to be in increasing order. The function modifies F in such a way that the mean value of the data points is PI. Said otherwise, the sum of the first and last θ is 2PI. If the second argument is not true, this is obtained by shifting all points θi. Otherwise, it is obtained by truncating the interval; note that truncation works only if PI is in the data interval.

[Endymion] (setq x5 (#:pw:alloc_function 5 1 5))
#Pw 5 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 
[Endymion] (defun ff(x) x)
ff
[Endymion] (#:pw:fill_function x5 'ff) 
#Pw 5 1 1 0 2 2 0 3 3 0 4 4 0 5 5 0 
[Endymion] (#:pw:make_symmetric x5 false)
#Pw 5 1.14159265358979 1 0 2.14159265358979 2 0 3.14159265358979 3 0 
4.14159265358979 4 0 5.14159265358979 5 0 
[Endymion] (setq x5 (#:pw:alloc_function 10 0 9))
#Pw 10 0 0 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0 
[Endymion] (#:pw:fill_function x5 'ff)
#Pw 10 0 0 0 1 1 0 2 2 0 3 3 0 4 4 0 5 5 0 6 6 0 7 7 0 8 8 0 9 9 0 
[Endymion] (#:pw:make_symmetric x5 true)
#Pw 8 0 0 0 1 1 0 2 2 0 3 3 0 4 4 0 5 5 0 6 6 0 6.28318530717959 
6.28318530717959 0 
[Endymion] (setq x5 (#:pw:alloc_function 7 0 6)) 
#Pw 7 0 0 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 
[Endymion] (#:pw:fill_function x5 'ff)
#Pw 7 0 0 0 1 1 0 2 2 0 3 3 0 4 4 0 5 5 0 6 6 0 
[Endymion] (#:pw:make_symmetric x5 true)
#Pw 7 0.283185307179586 0.283185307179586 0 1 1 0 2 2 0 3 3 0 4 4 0 5 5 0 6 6 0 
[Endymion] (setq x5 (#:pw:alloc_function 3 10 11)) 
#Pw 3 10 0 0 10.5 0 0 11 0 0 
[Endymion] (#:pw:make_symmetric x5 true)
#:pw:make_symmetric : Upper bound too small : -3.71681469282041
[Endymion] (#:pw:make_symmetric 'x5 true)
#:pw:make_symmetric : Not a pw function : x5

(#:pw:sub_line F) (Lisp function)

Given a PWfunction F, this function computes a and b such that F(z) and a*z+b take the same value at z0 and z1, and replaces f(z) by f(z)-(a*z+b). Here z=exp(i*θ), z0 and z1 correspond to the first and last θ. The function could be defined as follows.

get_z(F,i)::=buildq(#exp(%%i*F["theta",i])); /* The z associated to θi */ 
subline(F):=
 let(n = size(F),
   let([t1 = get_z(F,0), t2 = get_z(F,n-1), u = F[0], v = F[n-1], a=0,b=0],
      a:=(u-v)/(t1-t2),
      b:=(t1*v-t2*u)/(t1-t2),
      for i in 0...n-1 do decrement(F[i], b+a*get_z(F,i)),
      #cons(a,b))); /* return a and b as a Lisp cons */ 

(#:pw:alloc_function n a b) (Lisp function)

The function (#:pw:alloc_function n a b) creates a PW function, with n evaluation points, between a and b, filled with zeroes. Some examples of what can be done.

[Endymion] (setq x (#:pw:alloc_function 10 0 9))
#Pw 10 0 0 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0 
[Endymion] (#:pw:set_to_one x)
#Pw 10 0 1 1 1 1 1 2 1 1 3 1 1 4 1 1 5 1 1 6 1 1 7 1 1 8 1 1 9 1 1 
[Endymion] (#:pw:fill_function x (lambda (u)(+ 3 (* u #C(2 1)))))
#Pw 10 0 3 0 1 5 1 2 7 2 3 9 3 4 11 4 5 13 5 6 15 6 7 17 7 8 19 8 9 21 9 
[Endymion] (#:pw:set_theta x 3 3.3)
3.3
[Endymion] (#:pw:get_theta x 3)
3.3
[Endymion] (setcoef x 3 #C(9.6 3.3))
[3.3i+9.6]
[Endymion] (getcoef x 3)
[3.3i+9.6]
[Endymion] (#:pw:skip_unwanted x 2 5.5)
#Pw 5 2 7 2 3.3 9.6 3.3 4 11 4 5 13 5 5.5 14 5.5 
[Endymion] (#:pw:change_theta x (lambda(u) (* 2 u)))
#Pw 5 4 7 2 6.6 9.6 3.3 8 11 4 10 13 5 11 14 5.5 
[Endymion] (#:pw:shift_theta x -3)
#Pw 5 1 7 2 3.6 9.6 3.3 5 11 4 7 13 5 8 14 5.5 
[Endymion] (#:pw:sub_inf x 3)
#Pw 5 1 4 2 3.6 6.6 3.3 5 8 4 7 10 5 8 11 5.5 
[Endymion] (setq x5 (#:pw:alloc_function 5 1 5))
#Pw 5 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 
[Endymion] (#:pw:make_symmetric x5 false)
#Pw 5 1.14159265358979 0 0 2.14159265358979 0 0 3.14159265358979 0 0 
4.14159265358979 0 0 5.14159265358979 0 0 
[Endymion] (setq x5 (#:pw:alloc_function 10 0 9))
#Pw 10 0 0 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 7 0 0 8 0 0 9 0 0 
[Endymion] (#:pw:make_symmetric x5 true)
#Pw 8 0 0 0 1 0 0 2 0 0 3 0 0 4 0 0 5 0 0 6 0 0 6.28318530717959 0 0 

Valid XHTML 1.0 Strict back to home page © INRIA 2008 Last modified $Date: 2008/10/13 07:45:27 $