source: git/Singular/LIB/control.lib @ 4f950e

spielwiese
Last change on this file since 4f950e was 4385f6, checked in by Viktor Levandovskyy <levandov@…>, 17 years ago
*levandov: minor fix git-svn-id: file:///usr/local/Singular/svn/trunk@10138 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 42.8 KB
Line 
1version="$Id: control.lib,v 1.38 2007-06-20 22:31:00 levandov Exp $";
2category="System and Control Theory";
3info="
4LIBRARY:  control.lib     Algebraic analysis tools for System and Control Theory
5
6AUTHORS:  Oleksandr Iena       yena@mathematik.uni-kl.de
7@*        Markus Becker        mbecker@mathematik.uni-kl.de
8@*        Viktor Levandovskyy  levandov@mathematik.uni-kl.de
9
10SUPPORT: Forschungsschwerpunkt 'Mathematik und Praxis' (Project of Dr. E. Zerz
11and V. Levandovskyy), Uni Kaiserslautern
12
13MAIN PROCEDURES:
14  control(R);     analysis of controllability-related properties of R (using Ext modules)
15  controlDim(R);  analysis of controllability-related properties of R (using dimension)
16  autonom(R);     analysis of autonomy-related properties of R (using Ext modules)
17  autonomDim(R);  analysis of autonomy-related properties of R (using dimension)
18
19COMPONENT PROCEDURES:
20  leftKernel(R);       a left kernel of R
21  rightKernel(R);      a right kernel of R
22  leftInverse(R);      a left inverse of R
23  rightInverse(R);     a right inverse of R
24  smith(M);            a Smith form of a module M
25  colrank(M);          a column rank of M as of matrix
26  genericity(M);       analysis of the genericity of parameters
27  canonize(L);         Groebnerification for modules in the output of control or autonomy procs
28  iostruct(R);         computes an IO-structure of behavior given by a module R
29  findTorsion(R, I);   generators of the submodule of a module R, annihilated by the ideal I
30
31AUXILIARY PROCEDURES:
32  controlExample(s);   set up an example from the mini database inside of the library
33  view();              well-formatted output of lists, modules and matrices
34";
35
36LIB "homolog.lib";
37LIB "poly.lib";
38LIB "primdec.lib";
39LIB "matrix.lib";
40
41//---------------------------------------------------------------
42static proc Opt_Our()
43"USAGE: Opt_Our();
44RETURN: intvec, where previous options are stored
45PURPOSE: save previous options and set customized options
46"
47{
48  intvec v;
49  v=option(get);
50  option(redSB);
51  option(redTail);
52  return (v);
53}
54
55//-------------------------------------------------------------------------
56
57static proc space(int n)
58"USAGE:spase(n); n is an integer (number of needed spaces)
59RETURN:  string consisting of n spaces
60NOTE:  the procedure is used in the procedure 'view' to have a better formatted output
61"{
62  int i;
63  string s="";
64  for(i=1;i<=n;i++)
65  {
66    s=s+" ";
67  };
68  return(s);
69};
70//-----------------------------------------------------------------------------
71proc view(M)
72"USAGE:  view(M);   M is of any type
73RETURN:  no return value
74PURPOSE:  procedure for (well-) formatted output of modules, matrices, lists of modules, matrices; shows everything even if entries are long
75NOTE:  in case of other types( not 'module', 'matrix', 'list') works just as standard 'print' procedure
76EXAMPLE:  example view; shows an example
77"{
78  // to be replaced with something more feasible
79  if ( (typeof(M)=="module")||(typeof(M)=="matrix") )
80  {
81  int @R=nrows(M);
82  int @C=ncols(M);
83  int i;
84  int j;
85  list MaxLength=list();
86  int Size=0;
87  int max;
88  string s;
89
90  for(i=1;i<=@C;i++)
91  {
92    max=0;
93
94    for(j=1;j<=@R;j++)
95    {
96      Size=size( string( M[j,i] ) );
97      if( Size>max )
98      {
99        max=Size;
100      };
101    };
102    MaxLength[i] = max;
103  };
104
105  for(i=1;i<=@R;i++)
106  {
107    s="";
108    for(j=1;j<@C;j++)
109    {
110      s=s+string(M[i,j])+space( MaxLength[j]-size( string( M[i,j] ) ) ) +",";
111    };
112
113    s=s+string(M[i,j])+space( MaxLength[j]-size( string( M[i,j] ) ) );
114
115    if (i!=@R)
116    {
117      s=s+",";
118    };
119    print(s);
120  };
121
122  return();
123  };
124
125  if(typeof(M)=="list")
126  {
127    int sz=size(M);
128    int i;
129    for(i=1;i<=sz;i++)
130    {
131      view(M[i]);
132      print("");
133    };
134
135    return();
136  };
137  print(M);
138  return();
139}
140example
141{"EXAMPLE:";echo = 2;
142  ring r;
143  list L;
144  matrix M[1][3] = x2+x,y3-y,z5-4z+7;
145  L[1] = "a matrix:";
146  L[2] = M;
147  L[3] = "an ideal:";
148  L[4] = ideal(M);
149  view(L);
150};
151//--------------------------------------------------------------------------
152proc rightKernel(matrix M)
153"USAGE:  rightKernel(M);   M a matrix
154RETURN:  module
155PURPOSE: computes the right kernel of matrix M (a module of all elements v such that Mv=0)
156EXAMPLE: example rightKernel; shows an example
157"{
158  return(modulo(M,std(0)));
159}
160example
161{"EXAMPLE:";echo = 2;
162  ring r = 0,(x,y,z),dp;
163  matrix M[1][3] = x,y,z;
164  print(M);
165  matrix R = rightKernel(M);
166  print(R);
167  // check:
168  print(M*R);
169};
170//-------------------------------------------------------------------------
171proc leftKernel(matrix M)
172"USAGE:  leftKernel(M);   M a matrix
173RETURN:  module
174PURPOSE: computes left kernel of matrix M (a module of all elements v such that vM=0)
175EXAMPLE:  example leftKernel; shows an example
176"
177{
178  return( transpose( modulo( transpose(M),std(0) ) ) );
179}
180example
181{"EXAMPLE:";echo = 2;
182  ring r= 0,(x,y,z),dp;
183  matrix M[3][1] = x,y,z;
184  print(M);
185  matrix L = leftKernel(M);
186  print(L);
187  // check:
188  print(L*M);
189};
190//------------------------------------------------------------------------
191proc leftInverse(module M)
192"USAGE:  leftInverse(M);  M a module
193RETURN:  module
194PURPOSE: computes such a matrix L, that LM = Id;
195EXAMPLE: example leftInverse; shows an example
196NOTE: exists only in the case when M is free submodule
197"
198{
199  // it works also for the NC case;
200  int NCols = ncols(M);
201  module Id = freemodule(NCols);
202  module N  = transpose(M);
203  intvec old_opt=Opt_Our();
204  Id = std(Id);
205  matrix T;
206  // check the correctness (Id \subseteq M)
207  // via dimension: dim (M) = -1!
208  int d = dim_Our(N);
209  if (d != -1)
210  {
211    // No left inverse exists
212    return(matrix(0));
213  }
214  matrix T2 = lift(N, Id);
215  T2 =  transpose(T2);
216  option(set,old_opt);  // set the options back
217  return(T2);
218}
219example
220{
221  "EXAMPLE:";echo =2;
222  // a trivial example:
223  ring r = 0,(x,z),dp;
224  matrix M[2][1] = 1,x2z;
225  print(M);
226  print( leftInverse(M) );
227  kill r;
228  // derived from the example TwoPendula:
229  ring r=(0,m1,m2,M,g,L1,L2),Dt,dp;
230  matrix U[3][1];
231  U[1,1]=(-L2)*Dt^4+(g)*Dt^2;
232  U[2,1]=(-L1)*Dt^4+(g)*Dt^2;
233  U[3,1]=(L1*L2)*Dt^4+(-g*L1-g*L2)*Dt^2+(g^2);
234  module M = module(U);
235  module L = leftInverse(M);
236  print(L);
237  // check
238  print(L*M);
239};
240//-----------------------------------------------------------------------
241proc rightInverse(module R)
242"USAGE:  rightInverse(M);  M a module
243RETURN:  module
244PURPOSE: computes such a matrix L, that ML = Id
245EXAMPLE: example rightInverse; shows an example
246NOTE: exists only in the case when M is free submodule
247"
248{
249  return(transpose(leftInverse(transpose(R))));
250}
251example
252{ "EXAMPLE:";echo =2;
253  // a trivial example:
254  ring r = 0,(x,z),dp;
255  matrix M[1][2] = 1,x2+z;
256  print(M);
257  print( rightInverse(M) );
258  kill r;
259  // derived from the TwoPendula example:
260  ring r=(0,m1,m2,M,g,L1,L2),Dt,dp;
261  matrix U[1][3];
262  U[1,1]=(-L2)*Dt^4+(g)*Dt^2;
263  U[1,2]=(-L1)*Dt^4+(g)*Dt^2;
264  U[1,3]=(L1*L2)*Dt^4+(-g*L1-g*L2)*Dt^2+(g^2);
265  module M = module(U);
266  module L = rightInverse(M);
267  print(L);
268  // check
269  print(M*L);
270};
271//-----------------------------------------------------------------------
272static proc dim_Our(module R)
273{
274  int d;
275  if (attrib(R,"isSB")<>1)
276  {
277    R = std(R);
278  }
279  d = dim(R);
280  return(d);
281}
282//-----------------------------------------------------------------------
283static proc Ann_Our(module R)
284{
285  return(Ann(R));
286}
287//-----------------------------------------------------------------------
288static proc Ext_Our(int i, module R, list #)
289{
290  // mimicking 'Ext_R' from homolog.lib
291  int ExtraArg = ( size(#)>0 );
292  if (ExtraArg)
293  {
294    return( Ext_R(i,R,#[1]) );
295  }
296  else
297  {
298    return( Ext_R(i,R) );
299  }
300}
301//------------------------------------------------------------------------
302static proc is_zero_Our
303{
304  //just a copy of 'is_zero' from "poly.lib" patched with GKdim
305  int d = dim_Our(std(#[1]));
306  int a = ( d==-1 );
307  if( size(#) >1 ) { list L=a,d; return(L); }
308  return(a);
309  //  return( is_zero(R) ) ;
310};
311//------------------------------------------------------------------------
312static proc control_output(int i, int NVars, module R, module Ext_1, list Gen)
313"USAGE:  control_output(i, NVars, R, Ext_1),
314PURPOSE: where
315@*         i is integer (number of first nonzero Ext or a number of variables in a basering + 1 in case that all the Exts are zero),
316@*           NVars:  integer, number of variables in a base ring,
317@*           R:  module R (cokernel representation),
318@*           Ext_1:  module, the first Ext(its cokernel representation)
319RETURN:  list with all the contollability properties of the system which is to be returned in 'control' procedure
320NOTE:  this procedure is used in 'control' procedure
321"{
322  // TODO: NVars to be replaced with the global hom. dimension of basering!!!
323  // Is not clear what to do with gl.dim of qrings
324  string DofS = "dimension of the system:";
325  string Fn   = "number of first nonzero Ext:";
326  string Gen_mes = "Parameter constellations which might lead to a non-controllable system:";
327
328  module RK = rightKernel(R);
329  int d=dim_Our(std(transpose(R)));
330
331  if (i==1)
332  {
333    return(
334            list ( Fn,
335                   i,
336                  "not controllable , image representation for controllable part:",
337                    RK,
338                  "kernel representation for controllable part:",
339                   leftKernel( RK ),
340                  "obstruction to controllability",
341                   Ext_1,
342                  "annihilator of torsion module (of obstruction to controllability)",
343                   Ann_Our(Ext_1),
344                   DofS,
345                   d
346                 )
347          );
348  };
349
350  if(i>NVars)
351  {
352    return( list(  Fn,
353                   -1,
354                  "strongly controllable(flat), image representation:",
355                   RK,
356                  "left inverse to image representation:",
357                   leftInverse(RK),
358                   DofS,
359                   d,
360                   Gen_mes,
361                   Gen)
362          );
363  };
364
365  //
366  //now i<=NVars
367  //
368
369  if( (i==2) )
370  {
371    return( list( Fn,
372                  i,
373                 "controllable, not reflexive, image representation:",
374                  RK,
375                  DofS,
376                  d,
377                  Gen_mes,
378                  Gen)
379          );
380  };
381
382  if( (i>=3) )
383  {
384    return( list ( Fn,
385                   i,
386                  "reflexive, not strongly controllable, image representation:",
387                   RK,
388                   DofS,
389                   d,
390                      Gen_mes,
391                   Gen)
392          );
393  };
394};
395//-------------------------------------------------------------------------
396
397proc control(module R)
398"USAGE:  control(R);  R a module (R is the matrix of the system of equations to be investigated)
399RETURN:  list
400PURPOSE: compute the list of all the properties concerning controllability of the system (behavior), represented by the matrix R
401NOTE: the properties and corresponding data like controllability, flatness, dimension of the system, degree of controllability, kernel and image representations, genericity of parameters, obstructions to controllability, annihilator of torsion submodule and left inverse are investigated
402EXAMPLE:  example control; shows an example
403"
404{
405  int i;
406  int NVars=nvars(basering);
407  // TODO: NVars to be replaced with the global hom. dimension of basering!!!
408  int ExtIsZero;
409  intvec v=Opt_Our();
410  module R_std=std(R);
411  module Ext_1 = std(Ext_Our(1,R_std));
412
413  ExtIsZero=is_zero_Our(Ext_1);
414  i=1;
415  while( (ExtIsZero) && (i<=NVars) )
416  {
417    i++;
418    ExtIsZero = is_zero_Our( Ext_Our(i,R_std) );
419  };
420  matrix T=lift(R,R_std);
421  list l=genericity(T);
422  option(set,v);
423
424  return( control_output( i, NVars, R, Ext_1, l ) );
425}
426example
427{"EXAMPLE:";echo = 2;
428  // a WindTunnel example
429  ring A = (0,a, omega, zeta, k),(D1, delta),dp;
430  module R;
431  R = [D1+a, -k*a*delta, 0, 0],
432      [0, D1, -1, 0],
433      [0, omega^2, D1+2*zeta*omega, -omega^2];
434  R=transpose(R);
435  view(R);
436  view(control(R));
437};
438//--------------------------------------------------------------------------
439proc controlDim(module R)
440"USAGE:  controlDim(R); R a module (R is the matrix of the system of equations to be investigated)
441RETURN: list
442PURPOSE: computes list of all the properties concerning controllability of the system (behavior), represented by the  matrix R
443EXAMPLE:  example controlDim; shows an example
444NOTE: the properties and corresponding data like controllability, flatness, dimension of the system, degree of controllability, kernel and image representations, genericity of parameters, obstructions to controllability, annihilator of torsion submodule and left inverse are investigated.
445@* This procedure is analogous to 'control' but uses dimension calculations.
446@* The implemented approach works for full row rank matrices only (the check is done automatically).
447"
448{
449  if( nrows(R) != colrank(transpose(R)) )
450  {
451    return ("controlDim cannot be applied, since R does not have full row rank");
452  }
453  intvec     v = Opt_Our();
454  module R_std = std(R);
455  int        d = dim_Our(R_std);
456  int    NVars = nvars(basering);
457  int        i = NVars-d;
458  module Ext_1 = std(Ext_Our(1,R_std));
459  matrix     T = lift(R,R_std);
460  list       l = genericity(T);
461  option(set, v);
462  return( control_output( i, NVars, R, Ext_1, l));
463}
464example
465{"EXAMPLE:";echo = 2;
466  //a WindTunnel example
467  ring A = (0,a, omega, zeta, k),(D1, delta),dp;
468  module R;
469  R = [D1+a, -k*a*delta, 0, 0],
470      [0, D1, -1, 0],
471      [0, omega^2, D1+2*zeta*omega, -omega^2];
472  R=transpose(R);
473  view(R);
474  view(controlDim(R));
475};
476//------------------------------------------------------------------------
477proc colrank(module M)
478"USAGE: colrank(M); M a matrix/module
479RETURN: int
480PURPOSE: compute the column rank of M as of matrix
481NOTE: this procedure uses Bareiss algorithm
482"{
483  // NOte continued:
484  // which might not terminate in some cases
485  module M_red  = bareiss(M)[1];
486  int NCols_red = ncols(M_red);
487  return (NCols_red);
488}
489example
490{"EXAMPLE: ";echo = 2;
491  // de Rham complex
492  ring r=0,(D(1..3)),dp;
493  module R;
494  R=[0,-D(3),D(2)],
495    [D(3),0,-D(1)],
496    [-D(2),D(1),0];
497  R=transpose(R);
498  colrank(R);
499};
500
501//------------------------------------------------------------------------
502static proc autonom_output( int i, int NVars, module RC, int R_rank )
503"USAGE:  proc autonom_output(i, NVars, RC, R_rank)
504           i:  integer, number of first nonzero Ext or
505               just number of variables in a base ring + 1 in case that all the Exts are zero
506           NVars:  integer, number of variables in a base ring
507           RC: module, kernel-representation of controllable part of the system
508           R_rank: integer, column rank of the representation matrix
509PURPOSE: compute all the autonomy properties of the system which is to be returned in 'autonom' procedure
510RETURN:  list
511NOTE:  this procedure is used in 'autonom' procedure
512"
513{
514  int d=NVars-i;//that is the dimension of the system
515  string DofS="dimension of the system:";
516  string Fn = "number of first nonzero Ext:";
517  if(i==0)
518  {
519    return( list(  Fn,
520                   i,
521                  "not autonomous",
522                   "kernel representation for controllable part",
523                   RC,
524                   "column rank of the matrix",
525                   R_rank,
526                   DofS,
527                   d )
528          );
529  };
530
531  if( i>NVars )
532  {
533    return( list( Fn,
534                  -1,
535                  "trivial",
536                  DofS,
537                  d )
538          );
539  };
540
541  //
542  //now i<=NVars
543  //
544
545
546  if( i==1 )
547  // in case that NVars==1 there is no sense to consider the notion
548  // of strongly autonomous behavior, because it does not imply
549  // that system is overdetermined in this case
550  {
551    return( list ( Fn,
552                   i,
553                  "autonomous, not overdetermined",
554                   DofS,
555                   d )
556          );
557  };
558
559  if( i==NVars )
560  {
561    return( list(  Fn,
562                   i,
563                  "strongly autonomous(fin. dimensional),in particular overdetermined",
564                   DofS,
565                   d)
566          );
567  };
568
569  if( i<NVars )
570  {
571    return( list ( Fn,
572                   i,
573                  "overdetermined, not strongly autonomous",
574                   DofS,
575                   d)
576          );
577  };
578};
579//--------------------------------------------------------------------------
580proc autonomDim(module R)
581"USAGE:  autonomDim(R);   R a module (R is a matrix of the system of equations which is to be investigated)
582RETURN: list
583PURPOSE: computes the list of all the properties concerning autonomy of the system (behavior), represented by the matrix R
584NOTE: the properties and corresponding data like autonomy resp. strong autonomy, dimension of the system, autonomy degree, kernel representation and (over)determinacy are investigated.
585@* This procedure is analogous to 'autonom' but uses dimension calculations
586EXAMPLE:  example autonomDim; shows an example
587"
588{
589  int d;
590  int NVars  = nvars(basering);
591  module RT  = transpose(R);
592  module RC;  //for computation of controllable part if if exists
593  int R_rank = ncols(R);
594  d          = dim_Our( std(RT) );  //this is the dimension of the system
595  int      i = NVars-d;  //First non-zero Ext
596  if( d==0 )
597    {
598      RC = leftKernel(rightKernel(R));
599      R_rank=colrank(R);
600    }
601  return( autonom_output(i,NVars,RC,R_rank) );
602}
603example
604{"EXAMPLE:"; echo = 2;
605  // Cauchy1 example
606  ring r=0,(s1,s2,s3,s4),dp;
607  module R= [s1,-s2],
608            [s2, s1],
609            [s3,-s4],
610            [s4, s3];
611  R=transpose(R);
612  view( R );
613  view( autonomDim(R) );
614};
615//----------------------------------------------------------
616proc autonom(module R)
617"USAGE:  autonom(R);   R a module (R is a matrix of the system of equations which is to be investigated)
618RETURN:  list
619PURPOSE: find all the properties concerning autonomy of the system (behavior) represented by the  matrix R
620NOTE: the properties and corresponding data like autonomy resp. strong autonomy, dimension of the system, autonomy degree, kernel representation and (over)determinacy are investigated
621EXAMPLE: example autonom; shows an example
622"
623{
624  int NVars=nvars(basering);
625  int ExtIsZero;
626  module RT=transpose(R);
627  module RC;
628  int R_rank=ncols(R);
629  ExtIsZero=is_zero_Our(Ext_Our(0,RT));
630  int i=0;
631  while( (ExtIsZero)&&(i<=NVars) )
632  {
633    i++;
634    ExtIsZero = is_zero_Our(Ext_Our(i,RT));
635  };
636  if (i==0)
637  {
638    RC = leftKernel(rightKernel(R));
639    R_rank=colrank(R);
640  }
641  return(autonom_output(i,NVars,RC,R_rank));
642}
643example
644{"EXAMPLE:"; echo = 2;
645  // Cauchy
646  ring r=0,(s1,s2,s3,s4),dp;
647  module R= [s1,-s2],
648            [s2, s1],
649            [s3,-s4],
650            [s4, s3];
651  R=transpose(R);
652  view( R );
653  view( autonom(R) );
654};
655
656
657//----------------------------------------------------------
658proc genericity(matrix M)
659"USAGE:  genericity(M); M is a matrix/module
660RETURN:  list (of strings)
661PURPOSE: determine parametric expressions which have been assumed to be non-zero in the process of computing the Groebner basis
662NOTE: the output list consists of strings. The first string contains the variables only, whereas each further string contain a single polynomial in parameters.
663$* We strongly recommend to switch on the redSB and redTail options.
664@* The procedure is effective with the lift procedure for modules with parameters
665EXAMPLE:  example genericity; shows an example
666"
667{
668  // returns "-", if there are no parameters!
669  if (npars(basering)==0)
670  {
671    return("-");
672  }
673  list RT = evas_genericity(M); // list of strings
674  if ((size(RT)==1) && (RT[1] == ""))
675  {
676    return("-");
677  }
678  return(RT);
679}
680example
681{  // TwoPendula
682  "EXAMPLE:"; echo = 2;
683  ring r=(0,m1,m2,M,g,L1,L2),Dt,dp;
684  module RR =
685    [m1*L1*Dt^2, m2*L2*Dt^2, -1, (M+m1+m2)*Dt^2],
686    [m1*L1^2*Dt^2-m1*L1*g, 0, 0, m1*L1*Dt^2],
687    [0, m2*L2^2*Dt^2-m2*L2*g, 0, m2*L2*Dt^2];
688  module R = transpose(RR);
689  module SR = std(R);
690  matrix T = lift(R,SR);
691  genericity(T);
692  //-- The result might be different when computing reduced bases:
693  matrix T2;
694  option(redSB);
695  option(redTail);
696  module SR2 = std(R);
697  T2 =  lift(R,SR2);
698  genericity(T2);
699}
700//---------------------------------------------------------------
701static proc victors_genericity(matrix M)
702{
703  // returns "-", if there are no parameters!
704  if (npars(basering)==0)
705  {
706    return("-");
707  }
708  int plevel = printlevel-voice+2;
709  // M is a matrix over a ring with params and vars;
710  ideal I = ideal(M); // a list of entries
711  I = simplify(I,2); // delete 0's
712  // decompose every coeff in every poly
713  int i;
714  int s = size(I);
715  ideal NM;
716  poly p;
717  number num;
718  int  cl=1;
719  intvec ZeroVec; ZeroVec[nvars(basering)] = 0;
720  intvec W;
721  ideal Numero, Denomiro;
722  int cNu=0; int cDe=0;
723  for (i=1; i<=s; i++)
724  {
725    // remove contents and add them as polys
726    p   = I[i];
727    W   = leadexp(p);
728    if (W == ZeroVec) // i.e. just a coef
729    {
730      num    = denominator(leadcoef(p)); // from poly.lib
731      NM[cl] = numerator(leadcoef(p));
732      dbprint(p,"numerator:");
733      dbprint(p, string(NM[cl]));
734      cNu++; Numero[cNu]= NM[cl];
735      cl++;
736      NM[cl] = num; // denominator
737      dbprint(p,"denominator:");
738      dbprint(p, string(NM[cl]));
739      cDe++; Denomiro[cDe]= NM[cl];
740      cl++;
741      p = p - lead(p); // for the next cycle
742    }
743    if ( p!= 0)
744    {
745      num = content(p);
746      p   = p/num;
747      NM[cl] = denominator(num);
748      dbprint(p,"content denominator:");
749      dbprint(p, string(NM[cl]));
750      cNu++; Numero[cNu]= NM[cl];
751      cl++;
752      NM[cl] = numerator(num);
753      dbprint(p,"content numerator:");
754      dbprint(p, string(NM[cl]));
755      cDe++; Denomiro[cDe]= NM[cl];
756      cl++;
757    }
758    // it seems that the next elements will not have real influence
759    while( p != 0)
760    {
761      NM[cl] = leadcoef(p); // should be all integer, i.e. non-rational
762      dbprint(p,"coef:");
763      dbprint(p, string(NM[cl]));
764      cl++;
765      p = p - lead(p);
766    }
767  }
768  NM = simplify(NM,4); // delete identical
769  string newvars = parstr(basering);
770  def save = basering;
771  string NewRing = "ring @NR =" +string(char(basering))+",("+newvars+"),Dp;";
772  execute(NewRing);
773  // get params as variables
774  // create a list of non-monomials
775  ideal @L;
776  ideal F;
777  ideal NM = imap(save,NM);
778  NM = simplify(NM,8); //delete multiples
779  poly p,q;
780  cl = 1;
781  int j, cf;
782  for(i=1; i<=size(NM);i++)
783  {
784    p = NM[i] - lead(NM[i]);
785    if (p!=0)
786    {
787      //      L[cl] = p;
788      F  = factorize(NM[i],1); //non-constant factors only
789      cf = 1;
790      // factorize every polynomial
791      // throw away every monomial from factorization (also constants from above ring)
792      for (j=1; j<=size(F);j++)
793      {
794        q = F[j]-lead(F[j]);
795        if (q!=0)
796        {
797          @L[cl] = F[j];
798          cl++;
799        }
800      }
801    }
802  }
803  // return the result [in string-format]
804  @L = simplify(@L,2+4+8); // skip zeroes, doubled and entries, diff. by a constant
805  list SL;
806  for (j=1; j<=size(@L);j++)
807  {
808    SL[j] = string(@L[j]);
809  }
810  setring save;
811  return(SL);
812}
813//---------------------------------------------------------------
814static proc evas_genericity(matrix M)
815{
816  // called from the main genericity proc
817  ideal I = ideal(M);
818  I = simplify(I,2+4);
819  int s = ncols(I);
820  ideal Den;
821  poly p;
822  int i;
823  for (i=1; i<=s; i++)
824  {
825    p = I[i];
826    while (p !=0)
827    {
828      Den = Den, denominator(leadcoef(p));
829      p   = p-lead(p);
830    }
831  }
832  Den = simplify(Den,2+4);
833  string newvars = parstr(basering);
834  def save = basering;
835  string NewRing = "ring @NR =(" +string(char(basering))+"),("+newvars+"),Dp;";
836  execute(NewRing);
837  ideal F;
838  ideal Den = imap(save,Den);
839  Den = simplify(Den,2);
840  int s1 = ncols(Den);
841  for (i=1; i<=s1; i++)
842  {
843    Den[i] = normalize(Den[i]);
844    if ( Den[i] !=1)
845    {
846      F= F, factorize(Den[i],1);
847    }
848  }
849  F = simplify(F, 2+4+8);
850  ideal @L = F;
851  @L = simplify(@L,2);
852  list SL;
853  int c,j;
854  string Mono;
855  c = 1;
856  for (j=1; j<= ncols(@L);j++)
857  {
858    if (leadcoef(@L[j]) <0)
859    {
860      @L[j] = -1*@L[j];
861    }
862    if (((@L[j] - lead(@L[j]))==0 ) && (@L[j]!=0) ) //@L[j] is a monomial
863    {
864      Mono = Mono + string(@L[j])+ ","; // concatenation
865    }
866    else
867    {
868      c++;
869      SL[c] = string(@L[j]);
870    }
871  }
872  if (Mono!="")
873  {
874    Mono = Mono[1..size(Mono)-1]; // delete the last colon
875  }
876  SL[1] = Mono;
877  setring save;
878  return(SL);
879}
880
881//---------------------------------------------------------------
882proc canonize(list L)
883"USAGE:  canonize(L); L a list
884RETURN:  list
885PURPOSE: modules in the list are canonized by computing their reduced minimal (= unique up to constant factor w.r.t. the given ordering) Groebner bases
886ASSUME:  L is the output of control/autonomy procedures
887EXAMPLE:  example canonize; shows an example
888"
889{
890  list M = L;
891  intvec v=Opt_Our();
892  int s = size(L);
893  int i;
894  for (i=2; i<=s; i=i+2)
895  {
896    if (typeof(M[i])=="module")
897    {
898      M[i] = std(M[i]);
899      //      M[i] = prune(M[i]); // mimimal embedding: no need yet
900      //      M[i] = std(M[i]);
901    }
902  }
903  option(set, v); //set old values back
904  return(M);
905}
906example
907{  // TwoPendula with L1=L2=L
908  "EXAMPLE:"; echo = 2;
909  ring r=(0,m1,m2,M,g,L),Dt,dp;
910  module RR =
911    [m1*L*Dt^2, m2*L*Dt^2, -1, (M+m1+m2)*Dt^2],
912    [m1*L^2*Dt^2-m1*L*g, 0, 0, m1*L*Dt^2],
913    [0, m2*L^2*Dt^2-m2*L*g, 0, m2*L*Dt^2];
914  module R = transpose(RR);
915  list C = control(R);
916  list CC = canonize(C);
917  view(CC);
918}
919
920//----------------------------------------------------------------
921
922static proc elementof (int i, intvec v)
923{
924  int b=0;
925  for(int j=1;j<=nrows(v);j++)
926    {
927      if(v[j]==i)
928        {
929          b=1;
930          return (b);
931        }
932    }
933  return (b);
934}
935//-----------------------------------------------------------------
936proc iostruct(module R)
937"USAGE: iostruct( R ); R a module
938RETURN:  list L with entries: string s, intvec v, module P and module Q
939PURPOSE:  if R is the kernel-representation-matrix of some system, then we output a input-ouput representation Py=Qu of the system, the components that have been chosen as outputs(intvec v) and a comment s
940NOTE:  the procedure uses Bareiss algorithm
941EXAMPLE:  example iostruct; shows an example
942"
943{
944  // NOTE cont'd
945  //which might not terminate in some cases
946  list L = bareiss(R);
947  int R_rank = ncols(L[1]);
948  int NCols=ncols(R);
949  intvec v=L[2];
950  int temp;
951  int NRows=nrows(v);
952  int i,j;
953  int b=1;
954  module P;
955  module Q;
956  int n=0;
957
958  while(b==1)               //sort v through bubblesort
959    {
960      b=0;
961      for(i=1;i<NRows;i++)
962        {
963          if(v[i]>v[i+1])
964          {
965            temp=v[i];
966            v[i]=v[i+1];
967            v[i+1]=temp;
968            b=1;
969          }
970        }
971    }
972  P=R[v];                     //generate P
973  for(i=1;i<=NCols;i++)       //generate Q
974    {
975      if(elementof(i,v)==1)
976        {
977          i++;
978          continue;
979        }
980      Q=Q,R[i];
981    }
982  Q=simplify(Q,2);
983  string s="The following components have been chosen as outputs: ";
984  return (list(s,v,P,Q));
985}
986example
987{"EXAMPLE:";echo = 2;
988 //Example Antenna
989 ring r = (0, K1, K2, Te, Kp, Kc),(Dt, delta), (c,dp);
990 module RR;
991 RR =
992   [Dt, -K1, 0, 0, 0, 0, 0, 0, 0],
993   [0, Dt+K2/Te, 0, 0, 0, 0, -Kp/Te*delta, -Kc/Te*delta, -Kc/Te*delta],
994   [0, 0, Dt, -K1, 0, 0, 0, 0, 0],
995   [0, 0, 0, Dt+K2/Te, 0, 0, -Kc/Te*delta, -Kp/Te*delta, -Kc/Te*delta],
996   [0, 0, 0, 0, Dt, -K1, 0, 0, 0],
997   [0, 0, 0, 0, 0, Dt+K2/Te, -Kc/Te*delta, -Kc/Te*delta, -Kp/Te*delta];
998 module R = transpose(RR);
999 view(iostruct(R));
1000};
1001
1002//---------------------------------------------------------------
1003static proc smdeg(matrix N)
1004"USAGE: smdeg( N ); N a matrix
1005RETURN:  intvec
1006PURPOSE: returns an intvec of length 2 with the index of an element of N with smallest degree
1007"
1008{
1009  int n = nrows(N);
1010  int m = ncols(N);
1011  int d,d_temp;
1012  intvec v;
1013  int i,j;            // counter
1014
1015  if (N==0)
1016  {
1017    v = 1,1;
1018    return(v);
1019  }
1020
1021  for (i=1; i<=n; i++)
1022// hier wird ein Element ausgewaehlt(!=0) und mit dessen Grad gestartet
1023  {
1024    for (j=1; j<=m; j++)
1025    {
1026      if( deg(N[i,j])!=-1 )
1027      {
1028        d=deg(N[i,j]);
1029        break;
1030      }
1031    }
1032    if (d != -1)
1033    {
1034      break;
1035    }
1036  }
1037  for(i=1; i<=n; i++)
1038  {
1039    for(j=1; j<=m; j++)
1040    {
1041      d_temp = deg(N[i,j]);
1042      if ( (d_temp < d) && (N[i,j]!=0) )
1043      {
1044        d=d_temp;
1045      }
1046    }
1047  }
1048  for (i=1; i<=n; i++)
1049  {
1050    for (j=1; j<=m;j++)
1051    {
1052      if ( (deg(N[i,j]) == d) && (N[i,j]!=0) )
1053      {
1054        v = i,j;
1055        return(v);
1056      }
1057    }
1058  }
1059}
1060//---------------------------------------------------------------
1061static proc NoNon0Pol(vector v)
1062"USAGE: NoNon0Pol(v), v a vector
1063RETURN:  int
1064PURPOSE: returns 1, if there is only one non-zero element in v and 0 else
1065"{
1066  int i,j;
1067  int n = nrows(v);
1068  for( j=1; j<=n; j++)
1069  {
1070    if (v[j] != 0)
1071    {
1072      i++;
1073    }
1074  }
1075  if ( i!=1 )
1076  {
1077    i=0;
1078  }
1079  return(i);
1080}
1081//---------------------------------------------------------------
1082static proc extgcd_Our(poly p, poly q)
1083{
1084  ideal J;   //for extgcd-computations
1085  matrix T; //----------"------------
1086  list L;
1087  // the extgcd-command has a bug in versions before 2-0-7
1088  if ( system("version")<=2006 )
1089  {
1090    J = p,q; // J = N[k-1,k-1],N[k,k]; //J is of type ideal
1091    L[1] = liftstd(J,T);  //T is of type matrix
1092    if(J[1]==p) //this is just for the case the SINGULAR swaps the
1093    //      two elements due to ordering
1094    {
1095      L[2] = T[1,1];
1096      L[3] = T[2,1];
1097    }
1098    else
1099    {
1100      L[2] = T[2,1];
1101      L[3] = T[1,1];
1102    }
1103  }
1104  else
1105  {
1106    L=extgcd(p,q);
1107    //    L=extgcd(N[k-1,k-1],N[k,k]);
1108    //one can use this line if extgcd-bug is fixed
1109  }
1110  return(L);
1111}
1112static proc normalize_Our(matrix N, matrix Q)
1113"USAGE: normalize_Our(N,Q), N, Q are two matrices
1114PURPOSE: normalizes N and divides the columns of Q through the leading coefficients of the columns of N
1115RETURN: normalized matrix N and altered Q(according to the scheme mentioned in purpose). If number of columns of N and Q do not coincide, N and Q are returned unchanged
1116NOTE: number of columns of N and Q must coincide.
1117"
1118{
1119  if(ncols(N) != ncols(Q))
1120    {
1121      return (N,Q);
1122    }
1123  module M = module(N);
1124  module S = module(Q);
1125  int NCols = ncols(N);
1126  number n;
1127  for(int i=1;i<=NCols;i++)
1128    {
1129      n = leadcoef(M[i]);
1130      if( n != 0 )
1131        {
1132          M[i]=M[i]/n;
1133          S[i]=S[i]/n;
1134        }
1135     }
1136   N = matrix(M);
1137   Q = matrix(S);
1138   return (N,Q);
1139}
1140
1141//---------------------------------------------------------------
1142proc smith( module M )
1143"USAGE: smith(M); M a module/matrix
1144PURPOSE: computes the Smith normal form of a matrix
1145RETURN: a list of length 4 with the following entries:
1146@*      [1]: the Smith normal form S of M,
1147@*      [2]: the rank of M,
1148@*      [3]: a unimodular matrix U,
1149@*      [4]: a unimodular matrix V,
1150such that U*M*V=S. An warning is returned when no Smith form exists.
1151NOTE: The Smith form only exists over PIDs (principal ideal domains). Use global ordering for computations!
1152"
1153{
1154  if (nvars(basering)>1) //if more than one variable, return empty list
1155  {
1156    string s="The Smith-Form only exists for principal ideal domains";
1157    return (s);
1158  }
1159  matrix N = matrix(M);         //Typecasting
1160  int n = nrows(N);
1161  int m = ncols(N);
1162  matrix P = unitmat(n);       //left transformation matrix
1163  matrix Q = unitmat(m);       //right transformation matrix
1164  int k, i, j, deg_temp;
1165  poly tmp;
1166  vector v;
1167  list L;                      //for extgcd-computation
1168  intmat f[1][n];              //to save degrees
1169  matrix lambda[1][n];         //to save leadcoefficients
1170  intmat g[1][m];              //to save degrees
1171  matrix mu[1][m];             //to save leadcoefficients
1172  int ii;                       //counter
1173
1174  while ((k!=n) && (k!=m) )
1175  {
1176    k++;
1177    while ((k<=n) && (k<=m))  //outer while-loop for column-operations
1178    {
1179      while(k<=m )        //inner while-loop for row-operations
1180      {
1181        if( (n>m) && (k < n) && (k<m))
1182        {
1183          if( simplify((ideal(submat(N,k+1..n,k+1..m))),2)== 0)
1184          {
1185            return(N,k-1,P,Q);
1186          }
1187        }
1188        i,j = smdeg(submat(N,k..n,k..m)); //choose smallest degree in the remaining submatrix
1189        i=i+(k-1);                        //indices adjusted to the whole matrix
1190        j=j+(k-1);
1191        if(i!=k)                    //take the element with smallest degree in the first position
1192        {
1193          N=permrow(N,i,k);
1194          P=permrow(P,i,k);
1195        }
1196        if(j!=k)
1197        {
1198          N=permcol(N,j,k);
1199          Q=permcol(Q,j,k);
1200        }
1201        if(NoNon0Pol(N[k])==1)
1202        {
1203          break;
1204        }
1205        tmp=leadcoef(N[k,k]);
1206        deg_temp=ord(N[k,k]);             //ord outputs the leading degree of N[k,k]
1207        for(ii=k+1;ii<=n;ii++)
1208        {
1209          lambda[1,ii]=leadcoef(N[ii,k])/tmp;
1210          f[1,ii]=deg(N[ii,k])-deg_temp;
1211        }
1212        for(ii=k+1;ii<=n;ii++)
1213        {
1214          N = addrow(N,k,-lambda[1,ii]*var(1)^f[1,ii],ii);
1215          P = addrow(P,k,-lambda[1,ii]*var(1)^f[1,ii],ii);
1216          N,Q=normalize_Our(N,Q);
1217        }
1218      }
1219      if (k>n)
1220      {
1221        break;
1222      }
1223      if(NoNon0Pol(transpose(N)[k])==1)
1224      {
1225        break;
1226      }
1227      tmp=leadcoef(N[k,k]);
1228      deg_temp=ord(N[k,k]); //ord outputs the leading degree of N[k][k]
1229
1230      for(ii=k+1;ii<=m;ii++)
1231      {
1232        mu[1,ii]=leadcoef(N[k,ii])/tmp;
1233        g[1,ii]=deg(N[k,ii])-deg_temp;
1234      }
1235      for(ii=k+1;ii<=m;ii++)
1236      {
1237        N=addcol(N,k,-mu[1,ii]*var(1)^g[1,ii],ii);
1238        Q=addcol(Q,k,-mu[1,ii]*var(1)^g[1,ii],ii);
1239        N,Q=normalize_Our(N,Q);
1240      }
1241    }
1242    if( (k!=1) && (k<n) && (k<m) )
1243    {
1244      L = extgcd_Our(N[k-1,k-1],N[k,k]);
1245      if ( N[k-1,k-1]!=L[1] )  //means that N[k-1,k-1] is not a divisor of N[k,k]
1246      {
1247        N=addrow(N,k-1,L[2],k);
1248        P=addrow(P,k-1,L[2],k);
1249        N,Q=normalize_Our(N,Q);
1250
1251        N=addcol(N,k,-L[3],k-1);
1252        Q=addcol(Q,k,-L[3],k-1);
1253        N,Q=normalize_Our(N,Q);
1254        k=k-2;
1255      }
1256    }
1257  }
1258  if( (k<=n) && (k<=m) )
1259  {
1260    if( N[k,k]==0)
1261    {
1262      return(N,k-1,P,Q);
1263    }
1264  }
1265  return(N,k,P,Q);
1266}
1267example
1268{
1269  "EXAMPLE:";echo = 2;
1270  option(redSB);
1271  option(redTail);
1272  ring r   = 0,x,dp;
1273  module M = [x2,x,3x3-4], [2x2-1,4x,5x2], [2x5,3x,4x];
1274  print(M);
1275  list P = smith(M);
1276  print(P[1]);
1277  matrix N = matrix(M);
1278  matrix B = P[3]*N*P[4];
1279  print(B);
1280}
1281// see what happens when the matrix is already in Smith-Form
1282//  module M = [x,0,0],[0,x2,0],[0,0,x3];
1283//  list L = smith(M);
1284// print(L[1]);
1285//matrix N=matrix(M);
1286//matrix B=L[3]*N*L[4];
1287//print(B);
1288//---------------------------------------------------------------
1289static proc list_tex(L, string name,link l,int nr_loop)
1290"USAGE: list_tex(L,name,l), where L is a list, name a string, l a link
1291         writes the content of list L in a tex-file 'name'
1292RETURN: nothing
1293"
1294{
1295  if(typeof(L)!="list")  //in case L is not a list
1296  {
1297    texobj(name,L);
1298  }
1299  if(size(L)==0)
1300  {
1301  }
1302  else
1303  {
1304    string t;
1305    for (int i=1;i<=size(L);i++)
1306    {
1307      while(1)
1308      {
1309        if(typeof(L[i])=="string")  //Fehler hier fuer normalen output->nur wenn string in liste dann verbatim
1310        {
1311          t=L[i];
1312          if(nr_loop==1)
1313          {
1314            write(l,"\\begin\{center\}");
1315            write(l,"\\begin\{verbatim\}");
1316          }
1317          write(l,t);
1318          if(nr_loop==0)
1319          {
1320            write(l,"\\par");
1321          }
1322          if(nr_loop==1)
1323          {
1324            write(l,"\\end\{verbatim\}");
1325            write(l,"\\end\{center\}");
1326          }
1327          break;
1328        }
1329        if(typeof(L[i])=="module")
1330        {
1331          texobj(name,matrix(L[i]));
1332          break;
1333        }
1334        if(typeof(L[i])=="list")
1335        {
1336          list_tex(L[i],name,l,1);
1337          break;
1338        }
1339        write(l,"\\begin\{center\}");
1340        texobj(name,L[i]);
1341        write(l,"\\end\{center\}");
1342        write(l,"\\par");
1343        break;
1344      }
1345    }
1346  }
1347}
1348example
1349{
1350  "EXAMPLE:";echo = 2;
1351}
1352//---------------------------------------------------------------
1353proc verbatim_tex(string s, link l)
1354"USAGE: verbatim_tex(s,l), where s is a string and l a link
1355PURPOSE: writes the content of s in verbatim-environment in the file
1356         specified by link
1357RETURN: nothing
1358"
1359{
1360  write(l,"\\begin{verbatim}");
1361  write(l,s);
1362  write(l,"\\end{verbatim}");
1363  write(l,"\\par");
1364}
1365example
1366{
1367  "EXAMPLE:";echo = 2;
1368}
1369//---------------------------------------------------------------
1370proc findTorsion(module R, ideal TAnn)
1371"USAGE:  findTorsion(R, I);   R an ideal/matrix/module, I an ideal
1372RETURN:  module
1373PURPOSE: computes the Groebner basis of the submodule of R, annihilated by I
1374NOTE: especially helpful, when I is the annihilator of the t(R) - the torsion submodule of R. In this case, the result is the explicit presentation of t(R) as
1375the submodule of R
1376EXAMPLE: example findTorsion; shows an example
1377"
1378{
1379  // motivation: let R be a module,
1380  // TAnn is the annihilator of t(R)\subset R
1381  // compute the generators of t(R) explicitly
1382  ideal AS = TAnn;
1383  module S = R;
1384  if (attrib(S,"isSB")<>1)
1385  {
1386    S = std(S);
1387  }
1388  if (attrib(AS,"isSB")<>1)
1389  {
1390    AS = std(AS);
1391  }
1392  int nc  = ncols(S);
1393  module To = quotient(S,AS);
1394  To = std(NF(To,S));
1395  return(To);
1396}
1397example
1398{
1399  "EXAMPLE:";echo = 2;
1400  // Flexible Rod
1401  ring A = 0,(D1, D2), (c,dp);
1402  module R= [D1, -D1*D2, -1], [2*D1*D2, -D1-D1*D2^2, 0];
1403  module RR = transpose(R);
1404  list L = control(RR);
1405  // here, we have the annihilator:
1406  ideal LAnn = D1; // = L[10]
1407  module Tr  = findTorsion(RR,LAnn);
1408  print(RR);  // the module itself
1409  print(Tr); // generators of the torsion submodule
1410}
1411
1412
1413proc controlExample(string s)
1414"USAGE:  controlExample(s);   s a string
1415RETURN:  ring
1416PURPOSE: set up an example from the mini database by initalizing a ring and a module in a ring
1417NOTE: in order to see the list of available examples, execute @code{controlExample(\"show\");}
1418@* To use ab example, one has to do the following. Suppose one calls the ring, where the example will be activated, A. Then, by executing
1419@*  @code{def A = controlExample(\"Antenna\");} and @code{setring A;},
1420@* A will become a basering from the example \"Antenna\" with
1421the predefined system module R (transposed).
1422After that one can just execute @code{control(R);} respectively
1423@code{autonom(R);} to perform the control resp. autonomy analysis of R.
1424EXAMPLE: example controlExample; shows an example
1425"{
1426  list E, S, D; // E=official name, S=synonym, D=description
1427  E[1] = "Cauchy1";  S[1] = "cauchy1";  D[1] = "1-dimensional Cauchy equation";
1428  E[2] = "Cauchy2";  S[2] = "cauchy2";  D[2] = "2-dimensional Cauchy equation";
1429  E[3] = "Control1"; S[3] = "control1"; D[3] = "example of a simple noncontrollable system";
1430  E[4] = "Control2"; S[4] = "control2"; D[4] = "example of a simple controllable system";
1431  E[5] = "Antenna";  S[5] = "antenna";  D[5] = "antenna";
1432  E[6] = "Einstein"; S[6] = "einstein"; D[6] = "Einstein equations in vacuum";
1433  E[7] = "FlexibleRod"; S[7] = "flexible rod"; D[7] = "flexible rod";
1434  E[8] = "TwoPendula";  S[8] = "two pendula";  D[8] = "two pendula mounted on a cart";
1435  E[9] = "WindTunnel";  S[9] = "wind tunnel";D[9] = "wind tunnel";
1436  E[10] = "Zerz1";      S[10] = "zerz1"; D[10] = "example from the lecture of Eva Zerz";
1437  // all the examples so far
1438  int i;
1439  if ( (s=="show") || (s=="Show") )
1440  {
1441    print("The list of examples:");
1442    for (i=1; i<=size(E); i++)
1443    {
1444      printf("name: %s,  desc: %s", E[i],D[i]);
1445    }
1446    return();
1447  }
1448  string t;
1449  for (i=1; i<=size(E); i++)
1450  {
1451    if ( (s==E[i]) || (s==S[i]) )
1452    {
1453      t = "def @A = ex"+E[i]+"();";
1454      execute(t);
1455      return(@A);
1456    }
1457  }
1458  "No example found";
1459  return();
1460}
1461example
1462{
1463  "EXAMPLE:";echo = 2;
1464  controlExample("show");   // let us see all available examples:
1465  def B = controlExample("TwoPendula"); // let us set up a particular example
1466  setring B;
1467  print(R);
1468}
1469
1470//----------------------------------------------------------
1471//
1472//Some example rings with defined systems
1473//----------------------------------------------------------
1474//autonomy:
1475//
1476//----------------------------------------------------------
1477static proc exCauchy1()
1478{
1479  ring @r=0,(s1,s2),dp;
1480  module R= [s1,-s2],
1481            [s2, s1];
1482  R=transpose(R);
1483  export R;
1484  return(@r);
1485}
1486//----------------------------------------------------------
1487static proc exCauchy2()
1488{
1489  ring @r=0,(s1,s2,s3,s4),dp;
1490  module R= [s1,-s2],
1491            [s2, s1],
1492            [s3,-s4],
1493            [s4, s3];
1494  R=transpose(R);
1495  export R;
1496  return(@r);
1497}
1498//----------------------------------------------------------
1499static proc exZerz1()
1500{
1501  ring @r=0,(d1,d2),dp;
1502  module R=[d1^2-d2],
1503           [d2^2-1];
1504  R=transpose(R);
1505  export R;
1506  return(@r);
1507}
1508//----------------------------------------------------------
1509//control
1510//----------------------------------------------------------
1511static proc exControl1()
1512{
1513  ring @r=0,(s1,s2,s3),dp;
1514  module R=[0,-s3,s2],
1515           [s3,0,-s1];
1516  R=transpose(R);
1517  export R;
1518  return(@r);
1519}
1520//----------------------------------------------------------
1521static proc exControl2()
1522{
1523  ring @r=0,(s1,s2,s3),dp;
1524  module R=[0,-s3,s2],
1525           [s3,0,-s1],
1526           [-s2,s1,0];
1527  R=transpose(R);
1528  export R;
1529  return(@r);
1530}
1531//----------------------------------------------------------
1532static proc exAntenna()
1533{
1534  ring @r = (0, K1, K2, Te, Kp, Kc),(Dt, delta), dp;
1535  module R;
1536  R = [Dt, -K1, 0, 0, 0, 0, 0, 0, 0],
1537      [0, Dt+K2/Te, 0, 0, 0, 0, -Kp/Te*delta, -Kc/Te*delta, -Kc/Te*delta],
1538      [0, 0, Dt, -K1, 0, 0, 0, 0, 0],
1539      [0, 0, 0, Dt+K2/Te, 0, 0, -Kc/Te*delta, -Kp/Te*delta, -Kc/Te*delta],
1540      [0, 0, 0, 0, Dt, -K1, 0, 0, 0],
1541      [0, 0, 0, 0, 0, Dt+K2/Te, -Kc/Te*delta, -Kc/Te*delta, -Kp/Te*delta];
1542
1543  R=transpose(R);
1544  export R;
1545  return(@r);
1546}
1547
1548//----------------------------------------------------------
1549
1550static proc exEinstein()
1551{
1552  ring @r = 0,(D(1..4)),dp;
1553  module R =
1554  [D(2)^2+D(3)^2-D(4)^2, D(1)^2, D(1)^2, -D(1)^2, -2*D(1)*D(2), 0, 0, -2*D(1)*D(3), 0, 2*D(1)*D(4)],
1555  [D(2)^2, D(1)^2+D(3)^2-D(4)^2, D(2)^2, -D(2)^2, -2*D(1)*D(2), -2*D(2)*D(3), 0, 0, 2*D(2)*D(4), 0],
1556  [D(3)^2, D(3)^2, D(1)^2+D(2)^2-D(4)^2, -D(3)^2, 0, -2*D(2)*D(3), 2*D(3)*D(4), -2*D(1)*D(3), 0, 0],
1557  [D(4)^2, D(4)^2, D(4)^2, D(1)^2+D(2)^2+D(3)^2, 0, 0, -2*D(3)*D(4), 0, -2*D(2)*D(4), -2*D(1)*D(4)],
1558  [0, 0, D(1)*D(2), -D(1)*D(2), D(3)^2-D(4)^2, -D(1)*D(3), 0, -D(2)*D(3), D(1)*D(4), D(2)*D(4)],
1559  [D(2)*D(3), 0, 0, -D(2)*D(3),-D(1)*D(3), D(1)^2-D(4)^2, D(2)*D(4), -D(1)*D(2), D(3)*D(4), 0],
1560  [D(3)*D(4), D(3)*D(4), 0, 0, 0, -D(2)*D(4), D(1)^2+D(2)^2, -D(1)*D(4), -D(2)*D(3), -D(1)*D(3)],
1561  [0, D(1)*D(3), 0, -D(1)*D(3), -D(2)*D(3), -D(1)*D(2), D(1)*D(4), D(2)^2-D(4)^2, 0, D(3)*D(4)],
1562  [D(2)*D(4), 0, D(2)*D(4), 0, -D(1)*D(4), -D(3)*D(4), -D(2)*D(3), 0, D(1)^2+D(3)^2, -D(1)*D(2)],
1563  [0, D(1)*D(4), D(1)*D(4), 0, -D(2)*D(4), 0, -D(1)*D(3), -D(3)*D(4), -D(1)*D(2), D(2)^2+D(3)^2];
1564
1565  R=transpose(R);
1566  export R;
1567  return(@r);
1568}
1569
1570//----------------------------------------------------------
1571static proc exFlexibleRod()
1572{
1573  ring @r = 0,(D1, delta), dp;
1574  module R;
1575  R = [D1, -D1*delta, -1], [2*D1*delta, -D1-D1*delta^2, 0];
1576
1577  R=transpose(R);
1578  export R;
1579  return(@r);
1580}
1581
1582//----------------------------------------------------------
1583static proc exTwoPendula()
1584{
1585  ring @r=(0,m1,m2,M,g,L1,L2),Dt,dp;
1586  module R = [m1*L1*Dt^2, m2*L2*Dt^2, -1, (M+m1+m2)*Dt^2],
1587             [m1*L1^2*Dt^2-m1*L1*g, 0, 0, m1*L1*Dt^2],
1588             [0, m2*L2^2*Dt^2-m2*L2*g, 0, m2*L2*Dt^2];
1589
1590  R=transpose(R);
1591  export R;
1592  return(@r);
1593}
1594//----------------------------------------------------------
1595static proc exWindTunnel()
1596{
1597  ring @r = (0,a, omega, zeta, k),(D1, delta),dp;
1598  module R = [D1+a, -k*a*delta, 0, 0],
1599             [0, D1, -1, 0],
1600             [0, omega^2, D1+2*zeta*omega, -omega^2];
1601
1602  R=transpose(R);
1603  export R;
1604  return(@r);
1605}
Note: See TracBrowser for help on using the repository browser.