source: git/Singular/LIB/control.lib @ 3c4dcc

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