Скачать книгу

t(find(t==0))=eps; or equivalently, for i=1:length(t), if t(i)==0, t(i)=eps; end, end

      This statement changes any zero entry in the t vector into eps (2.2204e − 16). What is the real purpose of this statement? It is actually to remove the possibility of division‐by‐zero in the next statement, which is a mathematical expression having t in the denominator:

       x=sin(pi*t/D)./(pi*t/D);

      Using the modified function ‘ sinc1()’ with the third line activated, you will get the graphs with no hole like Figure 1.7b.

      Lastly, consider of the fourth line in ‘ sinc1()’, which is only one essential statement performing the main job:

       x=sin(pi*t/D)./(pi*t/D);

      What is the dot ( .) before division operator (/) for? Regarding this, authors gave you a piece of advice that you had better put a dot ( .) just before the arithmetic operators *(multiplication), /(division), and ̂(power) in the function definition so that the element‐by‐element (elementwise or termwise) operation can be done any time (Section 1.1.6 (A7)). To appreciate the existence of the dot ( .), we remove it from the M‐file defining ‘ sinc1()’, and run the following statements:

       >clf, plot(t,sinc1(t,D)), sinc1(t,D), sin(pi*t/D)/(pi*t/D) ans = -0.0183

      What do you see in the graphic window on the screen? To our surprise, nothing appears and that with no warning message! What is more surprising, the value of sinc1(t,D) or sin(pi*t/D)/(pi*t/D) shows up as a scalar. It is hoped that this accident will help you realize how important it is for right term‐by‐term operations to put dot ( .) before the arithmetic operators *, /, and ̂. By the way, aren't you curious about how MATLAB deals with a vector division without dot ( .)? If so, try with the following statements:

       >A=[1:10]; B=2*A; A/B, A*B'*(B*B')̂-1, A*pinv(B) ans = 0.5

      To understand this response of MATLAB, you can see Section 1.1.7 or 2.1.2.

      In this section, we looked over several sources of runtime error, hoping that it aroused reader's attention to runtime errors.

       global Gravity_Constant Dielectric_Constant

      %plot_sinc.m clear, clf global D D=0.5; b1=-2; b2=2; t=b1+[0:100]/100*(b2-b1); %passing the parameter(s) through arguments of the function subplot(221), plot(t, sinc1(t,D)), axis([b1 b2 -0.4 1.2]) %passing the parameter(s) through global variables subplot(222), plot(t, sinc2(t)), axis([b1 b2 -0.4 1.2])

function x=<b>sinc1</b><![CDATA[(t,D) if nargin<2, D=1; end t(find(t==0))=eps; x=sin(pi*t/D)./(pi*t/D); function x=<b>sinc2</b><![CDATA[(t) global D t(find(t==0))=eps; x=sin(pi*t/D)./(pi*t/D);

      Then, how convenient it would be, since you do not have to bother about passing the parameters. But as you get proficient in programming and handle many functions/routines that are involved with various sets of parameters, you might find that the global variable is not always convenient, because of the following reasons:

       Once a variable is declared as global, its value can be changed in any of the MATLAB functions having declared it as global, without being noticed by other related functions. Therefore, it is usual to declare only the constants as global and use long names (with all capital letters) as their names for easy identification.

       If some variables are declared as global and modified by several functions/routines, it is not easy to see the relationship and the interaction among the related functions in terms of the global variable. In other words, the program readability gets worse as the number of global variables and related functions increases.

      In this section, we see two kinds of routines that get a function name (string) with its parameters as its input argument and play with the function.

      First, let us look over the routine ‘ ez_plot1()’, which gets a function name ( ftn), its parameters ( p), and the lower/upper bounds ( bounds=[b1 b2]) of horizontal axis as its first, third, and second input arguments, respectively, and plots the graph of the given function over the interval set by the bounds. Since the given function may or may not have its parameter, the two cases are determined and processed by the number of input arguments (nargin) in the if‐else‐end block.

      %plot_sinc1.m D=1; b1=-2; b2=2; t=b1+[0:100]/100*(b2-b1); bounds=[b1 b2]; subplot(223), ez_plot1('sinc1',bounds,D) axis([b1 b2 -0.4 1.2]) subplot(224), ez_plot('sinc1',bounds,D) axis([b1 b2 -0.4 1.2])

function <b>ez_plot1</b><![CDATA[(ftn,bounds,p) b1=bounds(1); b2=bounds(2); t=b1+[0:100]/100*(b2-b1); if nargin<=2, x=feval(ftn,t); else x=feval(ftn,t,p); end plot(t,x) function <b>ez_plot</b><![CDATA[(ftn,bounds,varargin) b1=bounds(1); b2=bounds(2); t=b1+[0:100]/100*(b2-b1); x=feval(ftn,t,varargin{:}); plot(t,x)

      Now, let us see the routine ‘ ez_plot()’, which does the same plotting job as ‘ ez_plot1()’. Note that it has a MATLAB keyword varargin (variable length argument list) as its last input argument and passes it into the MATLAB built‐in function ‘ feval()’ as its last input argument. Since varargin can represent comma‐separated multiple parameters including expression/strings, it paves the high‐way for passing the parameters in relays. As the number of parameters increases, it becomes much more convenient to use varargin for passing the parameters than to deal with the parameters one‐by‐one as in ‘ ez_plot1()’. This technique will be widely used later in Chapter 4 (Nonlinear Equations), Chapter 5 (on numerical differentiation/integration), Chapter 6 (Ordinary Differential Equations), and Скачать книгу