File: ds_def.tex

package info (click to toggle)
dstooltk-doc 2.0-3
  • links: PTS
  • area: main
  • in suites: woody
  • size: 4,024 kB
  • ctags: 451
  • sloc: perl: 753; makefile: 49; sh: 8
file content (894 lines) | stat: -rw-r--r-- 45,212 bytes parent folder | download | duplicates (3)
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
\chapter{User-Defined Dynamical Systems}\label{define_ds}
In most instances, we expect that DsTool will be installed on a network of computers and
used by a variety of researchers.  It is not required, however, that each user
on a network utilize the same executable version of DsTool.  We have provided ways in
which each user may customize certain features of DsTool to suit his or her needs.  
An example of  DsTool customization is the installation of a user-defined dynamical system.
In this chapter we will detail this process.  More advanced customization, such 
as adding computational code to DsTool or adding animation to models, is
discussed in \unix{\$DSTOOL/my\_dstool/README}\index{customization}.

\section{Preliminaries}\label{prelims}
We presume DsTool is installed according to the instructions provided in
the DsTool installation information.  This procedure includes:
\begin{enumerate}
\item Defining UNIX environmental variables \unix{DSTOOL}, \unix{MY\_DSTOOL}, and \unix{ARCH}.
%\item \unix{DSTOOL\_DATA\_DIR}, 
\item Creating a local directory for DsTool.
\item Copying the contents of \unix{\$DSTOOL/my\_dstool} from the DsTool source code into the above subdirectory. 
%\item Defining \unix{UNIX} environmental variables \unix{DSTOOL}, \unix{DSTOOL\_COLOR\_DIR},
%and \unix{DSTOOL\_DATA\_DIR}.
%\item Creating a local directory for DsTool.
%\item Creating a subdirectory for user-defined models.
%\item Copying certain files from the DsTool source code into the above subdirectory.
\end{enumerate}
%The last two items are completed automatically by running the shellscript 
%\unix{install\_dsuser}.
Be certain that these steps are complete before proceeding.
%In addition, the following UNIX environmental variables are optional:
%\unix{DSTOOL\_TCL\_DIR} -- for changing the Tcl library,
%\unix{MY\_DSTOOL\_TCL\_DIR} -- for alternate Tcl interfaces,
%\unix{MY\_DSTOOL\_OOGL\_DIR} -- to hold Oogl files for custom versions,
%\unix{DSTOOL\_OOGL\_DIR} -- to hold Oogl files,
%\unix{DSTOOL\_HELP\_DIR} -- help files,
%\unix{DSTOOL\_DATA\_DIR} -- for keeping data, 
%\unix{DSTOOL\_PS\_PROLOG} -- for PostScript Prolog files.
%If any of these aren't defined, defaults will be provided.

\section{Installing a New Dynamical System in DsTool}\label{def_ds}\index{defining dynamical system}

The addition of a new dynamical system in DsTool is a two-step process.  The first
step entails writing a few procedures which define the set of governing equations for
the dynamical system (be it a vector field or a mapping) and the initial settings of
variables and parameters.  If desired, additional procedures may be written which
define derivatives (with respect to space, time, and parameters) and define an
arbitrary number of auxiliary scalar-valued functions.  The second step in the process
is to install the procedures into the libraries used to construct the executable
version of DsTool.  To help you complete the necessary steps, we provide the following checklist:
\begin{enumerate}
\item Define the dynamical system
	\begin{enumerate}
	\item Equations of motion
	\item Derivatives
	\item Inverse
	\item Auxillary equations
	\item Names and default ranges for variables
	\item Names and default ranges for parameters
	\item Names and default ranges for auxiliary functions
	\item Periodic variables
	\item Names of user-defined functions
	\end{enumerate}
\item Install the dynamical system
	\begin{enumerate}
	\item Initialization routine
	\item Title
	\item Compile source code
	\end{enumerate}
\end{enumerate}

The discussion which follows contains details of this process and a description of the
files and variables involved.  If you are not already there, change directories to
your local DsTool directory.


\subsection{Defining the Equations of Motion}\label{def_eqns}\index{defining dynamical system, equations} 
We shall use as an example a two-dimensional mapping $f=f_{\alpha,\gamma}$
defined by
\be\label{bball}\begin{array}{rcl}
  \phi_{j+1} &=& \phi_j + v_j, \\
  v_{j+1} &=& \alpha v_j - \gamma \cos(\phi_j + v_j).
\end{array}
\ee
These equations are a model for the dynamics of a ball bouncing\index{bouncing ball} on a sinusoidally
vibrating table.  The variable $\phi$ is proportional to the time, but because of the sinusoidal motion
of the table, we may think of $\phi$ as belonging to the circle parametrized by $[0,2 \pi)$.
The variable $v$ is proportional to the ball's velocity immediately after contact with the
table.  The parameter $\alpha$, $0 < \alpha \leq 1$ is the coefficient
of restitution for the ball; the parameter $\gamma > 0$ is the amplitude of the
table oscillations.  Essentially, the equations say that given the time of the $j$th impact 
($\phi_j$) and the ball's velocity at that time ($v_j$),  we know the time that the ball will next strike the
table ($\phi_{j+1}$), as well as the ball's velocity immediately after its next bounce ($v_{j+1}$).  
See~\cite{guckenheimerholmes} for information about the
dynamics of this system.

Suppose that a user wishes to study Equation~\ref{bball} numerically using DsTool.
The first task is to define the equations.  
First, copy the file \unix{GENERIC.c} to the file that you want
to edit.  For this example, call the target file \unix{bball\_def.c}.
You can use any text editor to edit \unix{bball\_def.c}.
The beginning of the file looks like:
{\csize \begin{verbatim}
#include <model_headers.h>

/* ------------------------------------------------------------------------
   function used to define the vector field or map
   ------------------------------------------------------------------------ */
int user_ds_func(f,x,p)
double *f,*x,*p;
{
}
\end{verbatim} }

First change the name of this function from user\_ds\_func() to
bball().  Then edit the function so that it properly defines the
mapping.  When you are finished, the function should look like:
{\csize \begin{verbatim}
#include <model_headers.h>

/* ------------------------------------------------------------------------
   function used to define the map
   ------------------------------------------------------------------------ */
int bball(f,x,p)
double *f,*x,*p;
{        
   f[0] = x[0] + x[1];
   f[1] = p[0] * x[1] - p[1] * cos(x[0] + x[1]);
}
\end{verbatim} }

The mapping is now defined.  We remind  novice C-programmers that arrays in C are indexed
from 0.  When bball() is called, the calling
routine is expected to pass in arrays \unix{f}, \unix{x}, and \unix{p}.  The input variables are
the current state of variables (\unix{x}) and the current parameters (\unix{p}):
\bea
\unix{x} &=& \{\unix{x[0]}, \unix{x[1]}\} = \{\phi_j, v_j\},\\
\unix{p} &=& \{\unix{p[0]}, \unix{p[1]}\} = \{\alpha, \gamma\}.
\eea
The function bball() places the new state in the array \unix{f}:
\bea \unix{f} &=& \{ \unix{f[0]}, \unix{f[1]} \} = \{\phi_{j+1}, v_{j+1}\}.
\eea

This  function\index{defining dynamical system, required}  {\em must} be defined in order 
to begin exploration of dynamics.  If the user does not wish to
input information about the system's derivative or inverse, and if
no auxiliary functions are desired, the user could proceed to Section~\ref{ic}.
For the purpose of illustration, however, we encourage the reader to 
continue reading. 

We remark at this point that although this system is a two-dimensional mapping,
the value $x[2]$ contains the current ``time.''\index{time}  In general, if there are 
$k$ dependent variables, then \unix{x[0]}, $\ldots$, \unix{x[k-1]} contain these variables and
\unix{x[k]} contains the independent variable.\index{independent variable}  
This is true both for maps and for vector fields. 

\subsection{Defining Derivative Information}\label{dfdx}\index{defining dynamical system, derivatives} 
If available, DsTool can use analytic information in
certain computational routines.  
Jacobian information is used in root-finding algorithms 
and for implicitly iterating diffeomorphisms backwards (when an explicit inverse
does not exist).  Detailed information about these algorithms is found in the DsTool Reference
Manual\index{reference manual}.

If derivative information is not provided by the
user, then DsTool will use finite difference-approximations.  This section will describe
how to write a function which provides an explicit Jacobian for Equation~\ref{bball}.
Because time is discrete for maps, it does not make sense to define a derivative with
respect to time.  
Currently, DsTool does not make use of derivatives with respect to time and parameters,
but we include them for the convenience of the user who wishes to extend the capabilities
of DsTool.

We now continue with the bouncing ball example by defining the Jacobian of $f$.
At the $j$th instant of time, the Jacobian is
\[ \left( \begin{array}{cc}
	\partial{f_1}/\partial{\phi_j} & \partial{f_1}/\partial{v_j} \\
	\partial{f_2}/\partial{\phi_j} & \partial{f_2}/\partial{v_j} \\
\end{array} \right) = \left( \begin{array}{cc}
	1 & 1 \\
\gamma \sin( \phi_j + v_j) & \alpha + \gamma \sin(\phi_j + v_j)
\end{array} \right)
\]
Find the section of the file \unix{bball\_def.c} which reads
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define the Jacobian
   ------------------------------------------------------------------------ */
/*
int user_jac(m,x,p)
double  **m, *x, *p;
{
}
*/
\end{verbatim}}
Using a text editor, modify this code segment to read
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define the Jacobian
   ------------------------------------------------------------------------ */
int bball_jac(m,x,p)
double  **m, *x, *p;
{
   double    temp;

   temp    = p[1] * sin( x[0] + x[1] );
   m[0][0] = 1.0;
   m[0][1] = 1.0;
   m[1][0] = temp;
   m[1][1] = p[0] + temp;
}
\end{verbatim}}

The routine which calls bball\_jac() sends in a matrix and two arrays which contain the 
current state and the current  parameters for $f_{\alpha, \gamma}$.  When bball\_jac() returns, it has filled
the matrix with the numerical Jacobian for $Df_{\alpha, \gamma}$ evaluated at the current state.
As remarked previously, writing a Jacobian routine is optional.

\subsection{Defining Information About an Inverse}\label{inverse}\index{defining dynamical system, inverse} 
In this section we show how to define an inverse or an approximate inverse for a
mapping.  We recall that the ``inverse function'' for a vector field is trivial, since
integrating the equations of motion backwards in time is the same as integrating
forward in time---except we pass in a negative time step to a numerical integrator.
Thus if we were installing a vector field, we would skip this section.  Moreover, it
frequently happens that a mapping does not have an inverse, nor is there any sort of
an approximate inverse.  In that case, do not edit the inverse routine at all.

For diffeomorphisms, it is sometimes difficult to iterate backwards in time.
The Reference Manual\index{reference manual} discusses Newton's method\index{Newton's method}
and implicitly iterating a mapping backwards\index{implicit inverse iteration}; 
it also briefly indicates some of the ways that Newton's method
can fail.  One of the most important  aspects of Newton's algorithm is its dependence on a ``good''
initial guess.  In the present section, we will discuss one way to provide a good guess.

For our bouncing ball example, it turns out that we can find an explicit inverse\index{inverse, explicit} for $f$
since $\alpha > 0$.
This inverse is the map given by
\be\label{bball_inv}\begin{array}{rcl}
  \phi_{j-1} &=& \phi_j - \frac{1}{\alpha}(\gamma \cos \phi_j + v_j), \\
  v_{j-1} &=& \frac{1}{\alpha}(\gamma \cos \phi_j + v_j).
\end{array}
\ee

To enter this inverse into DsTool, locate the section of \unix{bball\_def.c} which looks like
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define inverse or approximate inverse
   ------------------------------------------------------------------------ */
/*
int user_inv(y,x,p)
double    *y,*x,*p;
{
}
*/
\end{verbatim}}
\noindent and modify this section to produce 
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define inverse
   ------------------------------------------------------------------------ */
int bball_inv(y,x,p)
double    *y,*x,*p;
{
   double     temp;

   temp = ( p[1] * cos( x[0] ) + x[1] ) / p[0];
   y[0] = x[0] - temp;
   y[1] = temp;
}
\end{verbatim}}
% WAS:  f[0] = x[0] - temp;
%       f[1] = temp;
Suppose that our map did not have an explicit inverse (or we could not calculate it).
Then we would have to resort to using Newton's method to numerically solve for the inverse iterate
at each backward step.  To do so requires that we 
provide an initial guess for the inverse image of the current state.
If we provide a good guess for the inverse image, then possibly we will require only a few
Newton steps to ``sharpen'' our guess and converge to a solution (See the Reference Manual\index{reference manual}).
Suppose, for the sake of an example, that we were only interested in the bouncing ball map $f_{\alpha, \gamma}$
in the special case that $\gamma$ is small.  Then $f$ can be thought of as a perturbation
of the linear map $g$ defined by
\be\begin{array}{rcl}
  \phi_{j+1} &=& \phi_j + v_j, \\
  v_{j+1} &=& \alpha v_j,
\end{array}
\ee
and $g^{-1}$ can be written as:
\be\begin{array}{rcl}
  \phi_{j-1} &=& \phi_j - \frac{1}{\alpha} v_j, \\
  v_{j-1} &=& \frac{1}{\alpha} v_j.
\end{array}
\ee
In this case, we could code $g^{-1}$ into DsTool in place of $f^{-1}$.\index{inverse, approximate}
If we were to do this, we would modify \unix{bball\_def.c} to read:
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define approximate inverse
   ------------------------------------------------------------------------ */
int bball_approx_inv(y,x,p)
double    *y,*x,*p;
{
   y[0] = x[0] - x[1] / p[0];
   y[1] = x[1] / p[0];
}
\end{verbatim}}
Of course, we must inform DsTool whether to interpret the procedure as a definition of the actual inverse
or merely as an approximation; Section~\ref{ic} explains how this is done.

\subsection{Defining Auxiliary Functions}\label{auxeqn}\index{defining dynamical system, auxiliary functions} 
We continue with the above example.  Suppose that there is some scalar function
of the phase space variables, time, and parameters which we wish to monitor.
The scalar function may be a physically meaningful quantity such as the 
total energy of an (almost) conservative system,
or it could be a mathematically interesting quantity such as the
largest eigenvalue of the Jacobian matrix.  Sometimes it is useful to have functions 
which represent coordinate transformations.  For example, a particular dynamical system may 
be best described in terms of spherical coordinates.   Auxiliary functions can also
be used to monitor the distance from some set of interest.  For example, if a
system spends most of its time close to the sphere $|x|=1$ then it may be interesting
to define a function $|x|$. 

For our bouncing ball example, we will monitor the quantity $v^2$.  Since $v_j$ is proportional to 
the ball's velocity just after it strikes the table for the  $j$th time, we can think 
of $v_j^2$ as being a measure of the ball's kinetic energy at time $j$.  To define this function,
find the location in the file \unix{bball\_def.c} which reads
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define aux functions of the varbs, time, or params
   ------------------------------------------------------------------------ */
/*
int user_aux_func(f,x,p)
double *f,*x,*p;
{
}
*/
\end{verbatim}}
\noindent and edit it to produce
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define aux functions of the varbs, time, or params
   ------------------------------------------------------------------------ */
int bball_aux(f,x,p)
double *f,*x,*p;
{
   f[0] = x[1] * x[1];
}
	\end{verbatim}}
The number of auxiliary functions is completely arbitrary; it is not necessary to have
any auxiliary functions.  When this equation is called, the calling routine passes in
the current state of the phase space variables (in \unix{x}), the current parameters (in \unix{p}),
and an array (\unix{f}) which is filled up by this function.

\subsection{Defining Labels and Initial Conditions}\label{ic}\index{defining dynamical system, initial conditions} 
This section explains how to complete the definition of a dynamical
system by giving DsTool information about the structure of phase space,
the names of variables, and initial conditions.  

This section is split into subsections.  The subsections describe how to provide 
information on   variables,  parameters,  auxiliary functions,   periodic variables,
and numerical  algorithms.

Before we begin,
find the code segment of \unix{bball\_def.c} which looks like
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   Procedure to define default data for the dynamical system. NOTE: You
   may change the entries for each variable but DO NOT change the list of
   items.  If a variable is unused, NULL or zero the entry, as appropriate.
   ------------------------------------------------------------------------ */
int user_init()
{
/* ------------ define the dynamical system in this segment --------------- */
...
\end{verbatim}}
\noindent and change the name of the function from user\_init() to bball\_init().

\subsubsection{Variables}\label{varbs}
For our example, we have two spatial phase space variables, namely $\phi$ and $v$.
Because the equations of motion (Equation~\ref{bball}) are invariant under the
coordinate transformation $\phi \to \phi + 2n \pi$, $n \in \zed$, 
it is natural to display $\phi$ on the interval $[0, 2 \pi]$.  There is no ``natural''
interval to use in displaying the $v$ coordinate, since $v$
can be any real number, but we will choose the interval $[-30, 30]$ as a default range
on which to display $v$.
We will also need to choose a default initial condition $(\phi_0, v_0)$, which we arbitrarily
select to be the origin, $(0,0)$.

After implementing these choices, the relevant code in  bball\_init() looks like:
{\csize \begin{verbatim}
int            n_varb=2;                      /* dim of phase space           */
static char    *variable_names[]={"phi","v"}; /* list of phase varb names     */
static double  variables[]={0.,0.};           /* default varb initial values  */
static double  variable_min[]={0.,-30.};      /* default varb min for display */
static double  variable_max[]={TWOPI,30};     /* default varb max for display */
	\end{verbatim}}
We remark that \unix{TWOPI} ($2 \pi$)\index{TWOPI} and \unix{PI} ($\pi$)\index{PI} 
are two constants\index{constants} which the user may use in
defining a dynamical system. 

Although we have defined labels
and initial values for the {\em spatial} variables, the independent variable
(usually thought of as time)  is also considered to be a member
of every phase space.\index{time, member of phase space}  
The code which provides this information is given by:
{\csize \begin{verbatim}
static char    *indep_varb_name="time";  /* name of indep variable             */
static double  indep_varb_min=0.;        /* default indep varb min for display */
static double  indep_varb_max=10000.;    /* default indep varb max for display */
	\end{verbatim}}
In fact, this is the way the code looked when we copied it from \unix{GENERIC.c}, so
we do not need to make any changes to the code.  If we wanted to call the independent
variable ``iteration''  instead of ``time,'' or if we wanted to change the default plotting
range, then the code segment above would have to be appropriately modified.

\subsubsection{Parameters}
When examining bifurcations of our bouncing ball map, it is useful to graphically
depict (a subset of) the parameter space.  Since $0 < \alpha \leq 1$, we
choose the interval $[0,1]$ as the default range to display $\alpha$.  For 
$\gamma$, we choose $[0,25]$ as a default range.
As initial parameter values, we choose $(\alpha, \gamma) = (0.8, 10)$, since the dynamics
for these parameter values are fairly interesting.

To implement these choices, we edit a few more lines in bball\_init()
so that the code looks like:
{\csize \begin{verbatim}
int            n_param=2;                /* dim of parameter space          */
static char    *parameter_names[]={"alpha","gamma"}; /* list of param names */
static double  parameters[]={0.8,10.};   /* initial parameter values        */
static double  parameter_min[]={0.,0.};  /* default param min for display   */
static double  parameter_max[]={1.,25.}; /* default param max for display   */
	\end{verbatim}}

\subsubsection{Auxiliary Functions}
For our example, we have only a single function which we will call ``KE'' for kinetic energy.
From the definition of the function ($v^2$) and from the default plotting range for the
variable $v$, the interval $[0, 1000]$ is probably a suitable range on which to plot
the value of $v^2$.  Accordingly, we edit a few more lines in bball\_init():
{\csize \begin{verbatim}
int            n_funct=1;                /* number of user-defined functions */
static char    *funct_names[]={"KE"};    /* list of funct names; {""} if none*/
static double  funct_min[]={0};          /* default funct min for display    */
static double  funct_max[]={1000};       /* default funct max for display    */
	\end{verbatim}}

We remark that if we did not want to monitor any auxiliary functions then we would set 
\code{n\_funct=0}.  The array of function names, however, must contain at least an empty string
or else our code will not compile properly.  In other words, if there were no auxiliary quantities
of interest, then we could write \code{*funct\_names[]={""}}, but {\em not}
\code{*funct\_names[]={}}.

\subsubsection{Periodic Variables}
We must tell DsTool whether our phase space contains any periodic variables.  The
coding of this information is accomplished through two C-language constants:
\unix{EUCLIDEAN} or \unix{PERIODIC}.  If there are no periodic variables, then
the phase space is \unix{EUCLIDEAN}; if there is at least one periodic variable, the
phase space is classified as \unix{PERIODIC}.  For \unix{PERIODIC} phase spaces, we must
also inform DsTool as to which variables are periodic and what interval to use as
a fundamental domain.

For our example, since the equations of motion are invariant under the transformation
$\phi \to \phi + 2 n \pi$ for any integer $n$, we may consider $\phi$ to be a 
periodic variable with period $2 \pi$.  We may choose {\em any} interval of length
$2 \pi$ as a fundamental domain for the variable $\phi$.  Common choices are 
the intervals $[-\pi, \pi]$ and $[0, 2 \pi]$.  We make the latter choice.
To pass this information into DsTool, we edit yet a few more lines in bball\_init():
{\csize \begin{verbatim}
int           manifold_type=PERIODIC;   /* EUCLIDEAN or PERIODIC                */
static int    periodic_varb[]={TRUE, FALSE}; /* if PERIODIC, which varbs periodic? */
static double period_start[]={0.,0.};   /*if PERIODIC, begin fundamental domain */
static double period_end[]={TWOPI, 1.}; /*if PERIODIC, end of fundamental domain*/
	\end{verbatim}}

We remark on the variables \code{period\_start} and
\code{period\_end}.  If the $j$th coordinate is not periodic (\ie, the
value of \code{periodic\_varb}$[j]$ is \unix{FALSE}) then it does not
matter what \code{period\_start}$[j]$ and \code{period\_end}$[j]$ are because
the entries are ignored by DsTool.  Similarly, if the variable
\code{manifold\_type} is \unix{EUCLIDEAN}, then it doesn't matter what
values are given for the entries of \code{periodic\_varb}.  It is
always safe, of course, to set each entry of \code{periodic\_varb} to
\unix{FALSE}.  As mentioned in Section~\ref{varbs}, \unix{TWOPI} is a global
constant.

\subsubsection{Numerical Algorithms}
Continuing with our example, there remain a few pieces of information which 
we have not yet entered into DsTool.  We modify the last lines of code in bball\_init()
to obtain:
{\csize \begin{verbatim}
int        mapping_toggle=TRUE;         /* this is a map? TRUE or FALSE         */
int        inverse_toggle=EXPLICIT_INV; /* if so, is inverse FALSE, APPROX_INV, */
                                        /* or EXPLICIT_INV? FALSE for vec field */ 

/*  In this section, input NULL or the name of the function which contains...   */
int     (*def_name)()=bball;            /* the eqns of motion                   */
int     (*jac_name)()=bball_jac;        /* the jacobian (deriv w.r.t. space)    */
int     (*aux_func_name)()=bball_aux;   /* the auxiliary functions              */
int     (*inv_name)()=bball_inv;        /* the inverse or approx inverse        */
int     (*dfdt_name)()=NULL;            /* the deriv w.r.t time                 */
int     (*dfdparam_name)()=NULL;        /* the derivs w.r.t. parameters         */
	\end{verbatim}}
The first line means that our system is a mapping; if it were a vector field, we would
set \code{mapping\_toggle} to \unix{FALSE}.  The second line means that we have an
explicit inverse for our system.  In the event that a mapping does not have an explicit
inverse, then Newton's method will be used to calculate inverse iterates.  In this
event, we need to tell DsTool if there exists an approximate inverse (see
Section~\ref{inverse} or the Reference Manual\index{reference manual}) which can be used as an initial guess for
Newton's method.  If there is, then \code{inverse\_toggle} is set to \unix{APPROX\_INV};
otherwise, it is set to \unix{FALSE}.  We remark that if \code{mapping\_toggle} is set
to \unix{FALSE} (that is, the system is a vector field), then the value of
\code{inverse\_toggle} is ignored by DsTool.


In the last section of code, we provide DsTool with the names of any functions we defined previously.
For our example, this means filling in the names of the functions which compute the
equations of motion, the Jacobian, auxiliary functions, and the inverse.  If any of
these functions were omitted, then the user should enter \unix{NULL} instead of a
name. For example, the function which defines the inverse will be \unix{NULL} if you are
installing a vector field, and the function which defines the derivative with respect to
time should always be \unix{NULL} for mappings.

At this point, the user should save and exit the file \unix{bball\_def.c}.

\subsection{Installing a Defined Dynamical System}\label{install_sys}\index{defining dynamical system, installing}\index{installing dynamical system}
It is assumed that the reader has completed the steps in the preceding sections of this chapter.
In this section, we describe the installation of the dynamical system  defined using the
above  steps.  As an  illustration, we continue with the bouncing ball example.

Our first task is to modify the file \unix{user.c}.  There are two steps to this process: 
\begin{itemize}
\item Inform DsTool about the name of the initialization routine for the dynamical system we
desire to install.  In our bouncing ball example, this function is  bball\_init().
\item Enter this name into the DsTool list of dynamical systems, along with a title.
\end{itemize}

During the execution of DsTool, the user may select one of several installed dynamical systems.
The program maintains a list of installed models, along with the procedures which initialize
and define them.  
The user-defined models are maintained in the 
file \unix{user.c} of the user's local DsTool directory.  This file contains 
three relevant blocks of C code: the first block defines an array of categories used to collect dynamical systems
into related classes, the second consists of several lines beginning with the declaration
\unix{extern~int}, the last block is a C-language structure which contains titles for the 
models along with names of the models' initialization procedures.  The relevant pieces
of the file \unix{user.c}
delivered with DsTool contain the following code:
{\csize \begin{verbatim}
/* ----------------------------------------------------------------
 * INCLUDE USER DYNAMICAL SYSTEMS CATEGORIES HERE
 *
 * ----------------------------------------------------------------
 */
char *USER_DS_Category[] = { "User models" /* Category 0 */
                           };
 
/* ----------------------------------------------------------------
 * INCLUDE USER DYNAMICAL SYSTEM NAMES HERE
 *
 * We have put in the Lorenz system as an example
 * ----------------------------------------------------------------
 */
 
/* declare the model initialization procedure here */
extern int lorenz_init();
 
 
/* list the category, a short model name, and the initialization proc here */
struct DS_DataS USER_DS_Sel[]= {
  { 0, "Lorenz system", lorenz_init }
};
\end{verbatim}}

To tell DsTool the name of the initialization routine which defines our bouncing ball model,
we need to add the line
{\csize \begin{verbatim}
extern int  bball_init();
\end{verbatim}}
\noindent to the second block of code in  \unix{user.c}. 
To install our model, we replace the line of code
{\csize \begin{verbatim}
  { 0, "Lorenz system", lorenz_init }
\end{verbatim}}
with the line of code
{\csize \begin{verbatim}
  { 0, "Bouncing Ball", bball_init }
\end{verbatim}}
\noindent in the definition of the data structure \unix{USER\_DS\_Sel} within the third block of code.  
The variable \unix{USER\_DS\_Sel} is an array, each element of which is a 
data structure which defines a dynamical system.  The first element of the structure is 
a number which specifies the user category
to which the dynamical system belongs.  The category is
used to group together systems which share similar properties.  
These categories are defined in the first block of code.
Users cannot add dynamical systems to the standard list of categories.
However, they can create as many new categories as they wish, by modifying the category list like so:
{\csize \begin{verbatim}
char *USER_DS_Category[] = { "User models", /* Category 0 */
                             "Project with Bob", /* Category 1 */
                             "My favorite dynamical systems" /* Category 2 */
                           };
	\end{verbatim}}
This array provides the title for each category.  For our example, the category index is 0, so our bouncing ball
model belongs to the category named ``User models.''  (Recall
that arrays in C are indexed from
0 so \code{DS\_Category}$[0]$ is not an invalid array index.)  Every dynamical 
system must belong to a valid category.  

The next element of the dynamical system data structure is the title of the system being defined.
We have chosen ``Bouncing Ball'' as the title of our system.  Any descriptive title will do, provided
that the length of the title is not larger than the global constant \unix{MAX\_LEN\_DS\_TITLE}.
The value of this constant is found in the  file \unix{\$DSTOOL/src/include/constants.h}.

The last element is the name of the function which contains the initialization routine
for the new dynamical system.  For our example, the name is \unix{bball\_init}.

Note that each dynamical system data structure must be enclosed by braces and followed
by a comma.  That is, all except the last.  The last element in the array of dynamical systems
(our new dynamical system ``Bouncing Ball'' in our example code) should not have a trailing comma.

We are now ready to compile the source code we have written.
To do this, edit the \unix{Makefile} in your local DsTool directory.
Add the file \unix{bball\_def.c} to the \unix{USER\_SRCS}
list of files, and the file \unix{bball\_def.o} to the \unix{USER\_OBJS} list of files.
In the example described above, the corresponding Makefile entry would be:
{\csize \begin{verbatim}
        USER_SRCS = user.c bball_def.c
        USER_OBJS = user.o bball_def.o
	\end{verbatim}}
Now save and exit the \unix{Makefile}. 

If our model compiles without errors, we can create a custom version of DsTool
called \unix{my\_dstool}.  To do this, execute the command \unix{make} in your
local DsTool directory.  

Once this is done, you can ensure that this version of DsTool is executed by settting
the UNIX environmental variable \unix{MY\_DSTOOL} to your local DsTool directory.  
When the script \unix{dstool\_tk} is run from any directory, it will execute the binary 
\unix{\$MY\_DSTOOL/bin/\$ARCH/my\_dstool}.  A message will be printed confirming which binary
is being executed.
This version of DsTool will include the bouncing ball equations among its installed dynamical
systems.

\section{A Vector Field Example: Duffing's Equations}\label{vfield}
In this section we present an example of installing a user-defined vector field into DsTool.
It is assumed that the reader is familiar with the material in Section~\ref{def_ds}.

Our task is to install the vector field defined by the equations
\be\label{duff1}\begin{array}{rcl}
  \dot{u} &=& v, \\
  \dot{v} &=& u - u^3 - \delta v - \gamma \cos \omega t.
\end{array}
\ee
This system is known as Duffing's equations and we direct the reader to 
\cite{guckenheimerholmes} and references therein for an exposition of the dynamics of this system.

To define and install this system, change to your local DsTool directory
and copy the file \unix{GENERIC.c} to the file \unix{userduffing\_def.c}.
Use any text editor to edit \unix{userduffing\_def.c}.

The segment of code which defines the equations of motion (Equation~\ref{duff1}) 
will be called userduffing().  This function is defined as follows:
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define the vector field 
   ------------------------------------------------------------------------ */
int userduffing(f,x,p)
double *f,*x,*p;
{
   f[0] = x[1];
   f[1] = x[0] - x[0]*x[0]*x[0] - p[0]*x[1] - p[1]*cos( p[2]*x[2] );
}
	\end{verbatim}}
\noindent Here we have defined the variables and parameters as
\bea
	\unix{x} &=& \{ \unix{x[0]}, \unix{x[1]} \} = \{ u, v \}, \\
	\unix{p} &=& \{ \unix{p[0]}, \unix{p[1]}, \unix{p[2]} \} = \{ \delta, \gamma, \omega \}.
\eea
As usual, the independent variable is stored after the spatial variables so that
\unix{x[2]} is time.  The function userduffing() returns in the array \unix{f} the strength of the
vector field with parameters \unix{p}, evaluated at the point \unix{x}.

We now define the Jacobian of Equation~\ref{duff1} by writing the function userduffing\_jac():
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define the Jacobian
   ------------------------------------------------------------------------ */
int userduffing_jac(m,x,p)
double  **m, *x, *p;
{
   m[0][0] = 0.0;
   m[0][1] = 1.0;
   m[1][0] = 1.0 - 3.0 * x[0] * x[0];
   m[1][1] = -p[0];
}
\end{verbatim}}

Since our equations are for a vector field, we do not need to define an inverse function.
Our vector field is time-dependent, so we can define a function which returns
the temporal derivatives of the vector field.   This function is not yet used by DsTool, and
there is no template for such a function 
in \unix{GENERIC.c}, but it is easy enough to write:
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define temporal derivatives
   ------------------------------------------------------------------------ */
int userduffing_dfdt(f,x,p)
double  *f, *x, *p;
{
   f[0] = 0.0;
   f[1] = -p[1] * p[2] * sin( p[2] * x[2] ); 
}
\end{verbatim}}

Since our vector field is Hamiltonian for $\delta = 0$, we choose 
\[ H(u,v) = \frac{v^2}{2} - \frac{u^2}{2} + \frac{u^4}{4}
\]
as an auxiliary function.  We will also define a second auxiliary function.  Since our vector field is
periodic in time (with period $2 \pi / \omega$), it is a common technique to look at the time-$2 \pi / \omega$
map in order to better understand the dynamics.  This ``stroboscopic map'' can also be thought
of as a Poincar\'e map for the extended phase space.  
We are thus interested in the times $t$  for which $\sin( wt + t_0) = 0$.  Choosing $t_0 = 0$
we define the procedure userduffing\_aux() by:
{\csize \begin{verbatim}
/* ------------------------------------------------------------------------
   function used to define aux functions of the varbs, time, or params
   ------------------------------------------------------------------------ */
int userduffing_aux(f,x,p)
double *f,*x,*p;
{
   double   temp;

   temp = 0.5 * x[0] * x[0];
   f[0] = 0.5 * x[1] * x[1] - temp + temp * temp;
   f[1] = sin( p[2] * x[2] );
}
\end{verbatim}}

We are now ready to define the labels and initial conditions for Duffing's equations
by writing the function userduffing\_init().  We choose $[-2, 2]$ as default plotting ranges for both 
$u$ and $v$.  Initializing the variables is straightforward:
{\csize \begin{verbatim}
int userduffing_init()
{
/* ------------ define the dynamical system in this segment --------------- */

int            n_varb=2;                  /* dim of phase space           */
static char    *variable_names[]={"u","v"}; /* list of phase varb names   */
static double  variables[]={0.5,0.5};     /* default varb initial values  */
static double  variable_min[]={-2.,-2.};  /* default varb min for display */
static double  variable_max[]={2.,2.};    /* default varb max for display */

static char    *indep_varb_name="time";   /* name of indep variable             */
static double  indep_varb_min=0.;         /* default indep varb min for display */
static double  indep_varb_max=1000;       /* default indep varb max for display */
\end{verbatim}}

Defining the parameter ranges is somewhat arbitrary. Sometimes it is difficult to 
tell {\em a priori} what range of parameters will provide interesting bifurcations.
This is not a big problem
since it is a trivial matter to change the range upon which a function (or parameter) is plotted
once within DsTool.  
We choose $[0,1]$ as a range for each parameter.  We choose $(\delta_0, \gamma_0, \omega_0)
= (0.25, 0.4, 1.0)$:
{\csize \begin{verbatim}
int           n_param=3;                  /* dim of parameter space        */
static char   *parameter_names[]={"delta","gamma", "w"}; /* list of param names */
static double parameters[]={0.25,0.4,1.}; /* initial parameter values      */
static double parameter_min[]={0.,0.,0.}; /* default param min for display */
static double parameter_max[]={1.,1.,1.}; /* default param max for display */
\end{verbatim}}

The initialization of our two auxiliary functions is accomplished by the code segment:
{\csize \begin{verbatim}
int            n_funct=2;               /* number of user-defined functions */
static char    *funct_names[]={"H", "P_Section"}; /* list of funct names; {""} if none */
static double  funct_min[]={-4.,-1.};   /* default funct min for display    */
static double  funct_max[]={4.,1.};     /* default funct max for display    */
\end{verbatim}}
\noindent As in the case with parameters, it is sometimes difficult to choose {\em a priori}
what appropriate ranges for the functions should be.  

The manifold type for Duffing's equations is \unix{EUCLIDEAN} since we do not have any 
periodic spatial variables.  Thus we do not need to modify the following segment of code:
{\csize \begin{verbatim}
int           manifold_type=EUCLIDEAN; /* EUCLIDEAN or PERIODIC                 */
static int    periodic_varb[]={FALSE, FALSE}; /* if PERIODIC, which varbs periodic? */
static double period_start[]={0.,0.};  /* if PERIODIC, begin fundamental domain */
static double period_end[]={1., 1.};   /* if PERIODIC, end of fundamental domain*/
\end{verbatim}}

The last segment of code we need to modify is the segment which tells DsTool which numerical algorithms
may be used on the Duffing's equations.  
We complete the definition of userduffing\_init() with the code segment:
{\csize \begin{verbatim}
int           mapping_toggle=FALSE;       /* this is a map? TRUE or FALSE         */
int           inverse_toggle=FALSE;       /* if so, is inverse FALSE, APPROX_INV, */
                                        /* or EXPLICIT_INV? FALSE for vec field */ 

/*  In this section, input NULL or the name of the function which contains...   */
int     (*def_name)()=userduffing;          /* the eqns of motion                   */
int     (*jac_name)()=userduffing_jac;      /* the jacobian (deriv w.r.t. space)    */
int     (*aux_func_name)()=userduffing_aux; /* the auxiliary functions              */
int     (*inv_name)()=NULL;             /* the inverse or approx inverse        */
int     (*dfdt_name)()=userduffing_dfdt;    /* the deriv w.r.t time                 */
int     (*dfdparam_name)()=NULL;        /* the derivs w.r.t. parameters         */
\end{verbatim}}


As in Section~\ref{def_ds}, we now need to edit two other files.
We edit \unix{Makefile} and add \unix{userduffing\_def.c}
to the \unix{USER\_SRCS} list, and add \unix{userduffing\_def.o} to the
\unix{USER\_OBJS} list.  We also edit the file
\unix{user.c} and add the lines
{\csize \begin{verbatim}
extern int  userduffing_init();
	\end{verbatim}}
\noindent and 
{\csize \begin{verbatim}
{0, "Duffing's Eqns", userduffing_init},
	\end{verbatim}}
\noindent to  the second and third blocks of code, respectively.

Typing \unix{make}
will create a local executable of DsTool which includes Duffing's equations among its installed dynamical
systems.


\subsection{A Few Remarks on the Definition of Duffing's Equations}
Recall that when we installed Duffing's equations as a time-dependent vector field,
we defined $\sin \omega t$ as an auxiliary function and claimed that we could
use it to study the time-$2 \pi/\omega$ stroboscopic map.  
In theory, there is nothing wrong with
this, however in practice we will encounter numerical errors in the evaluation of 
transcendental functions such as $\sin \omega t$ for large values of $t$.  
Since we are often interested in generating
Poincar\'e maps for extremely long times, and since the function $\cos \omega t$
also appears in the definition of our vector field, the user may want to extend phase space
by introducing the variable $\theta$.  Then we can rewrite Duffing's
equations in the form
\be\begin{array}{rcl}
  \dot{u} &=& v, \\
  \dot{v} &=& u - u^3 - \delta v - \gamma \cos \omega \theta, \\
  \dot{\theta} &=& 1,
\end{array}
\ee
where $(u,v,\theta) \in \real^2 \times S^1$, and $S^1$ is the circle of length $2 \pi/ \omega$.
That is, $\theta$ takes values in $[0, 2 \pi/ \omega)$.
The  problem with this formulation is that DsTool {\em cannot handle periodic variables
whose length depends on a parameter!}  To overcome this difficulty, we change coordinates
via the transformation $\psi = \omega \theta$.  Thus we could study Duffing's  equations
on extended phase space in the form
\be\label{duff2}\begin{array}{rcl}
  \dot{u} &=& v, \\
  \dot{v} &=& u - u^3 - \delta v - \gamma \cos \psi, \\
  \dot{\psi} &=& \omega,
\end{array}
\ee
where $(u,v,\psi) \in \real^2 \times S^1$, and $S^1$ is now the circle of length $2 \pi$.

The advantage to an extended phase space such as we have for Equation~\ref{duff2}
is that it is trivial to plot Poincar\'e sections for this set of equations because we
can make $\psi$ a periodic variable.  This allows us to request that DsTool only plot
points when $\theta=\theta_0$ for some $\theta_0$. 
In contrast, DsTool {\em never treats time as a periodic variable},
so we needed to define the auxiliary function $\sin \omega t$ in order to be able to generate a
Poincar\'e map for Duffing's equations.


\section{Deleting Dynamical Systems}\index{deleting dynamical system}
Suppose that we want to remove the dynamical system ``Bouncing Ball'' from 
section \ref{def_ds}, 
which is defined in the file \unix{bball\_def.c}.  To remove this:
\begin{enumerate}
\item Edit the \unix{Makefile} in your local DsTool directory.  Delete the name of the file
which contains the dynamical system from the \unix{USER\_SRCS}
list and the name of the corresponding object file from the \unix{USER\_OBJS} list. 
In our example, we would remove the file names \unix{bball\_def.c} and \unix{bball\_def.o} 
from the \unix{Makefile}.

\item Edit the file \unix{user.c} and
delete all references to the dynamical system you wish to remove.  To remove the Bouncing ball system,
delete  the lines
{\csize \begin{verbatim}
extern int	bball_init();
	\end{verbatim}}
and
{\csize \begin{verbatim}
{0, "Bouncing Ball", bball_init},
	\end{verbatim}}
from the file.  

\item Remake your custom executable as explained in previous sections.
\end{enumerate}


We note that you cannot delete any of the standard models that come 
with DsTool.  You can only delete models that you have previously 
added to your own custom executable.