source: git/Singular/LIB/control.lib @ 0266ac

fieker-DuValspielwiese
Last change on this file since 0266ac was 226747, checked in by Viktor Levandovskyy <levandov@…>, 19 years ago
*levandov: return replaced, some typos corrected git-svn-id: file:///usr/local/Singular/svn/trunk@8291 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 41.6 KB
Line 
1version="$Id: control.lib,v 1.33 2005-05-23 15:47:35 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
401EXAMPLE:  example control; shows an example
402"
403{
404  int i;
405  int NVars=nvars(basering);
406  // TODO: NVars to be replaced with the global hom. dimension of basering!!!
407  int ExtIsZero;
408  intvec v=Opt_Our();
409  module R_std=std(R);
410  module Ext_1 = std(Ext_Our(1,R_std));
411
412  ExtIsZero=is_zero_Our(Ext_1);
413  i=1;
414  while( (ExtIsZero) && (i<=NVars) )
415  {
416    i++;
417    ExtIsZero = is_zero_Our( Ext_Our(i,R_std) );
418  };
419  matrix T=lift(R,R_std);
420  list l=genericity(T);
421  option(set,v);
422
423  return( control_output( i, NVars, R, Ext_1, l ) );
424}
425example
426{"EXAMPLE:";echo = 2;
427  // a WindTunnel example
428  ring A = (0,a, omega, zeta, k),(D1, delta),dp;
429  module R;
430  R = [D1+a, -k*a*delta, 0, 0],
431      [0, D1, -1, 0],
432      [0, omega^2, D1+2*zeta*omega, -omega^2];
433  R=transpose(R);
434  view(R);
435  view(control(R));
436};
437//--------------------------------------------------------------------------
438proc controlDim(module R)
439"USAGE:  controlDim(R); R a module (R is the matrix of the system of equations to be investigated)
440RETURN: list
441PURPOSE: computes list of all the properties concerning controllability of the system (behavior), represented by the  matrix R
442EXAMPLE:  example controlDim; shows an example
443NOTE: this procedure is analogous to 'control' but uses dimension calculations.This approach works for full row rank matrices only.
444"
445{
446  if( nrows(R) != colrank(transpose(R)) )
447  {
448    return ("controlDim cannot be applied, since R does not have full row rank");
449  }
450  intvec v=Opt_Our();
451  module R_std=std(R);
452  int d=dim_Our(R_std);
453  int NVars=nvars(basering);
454  int i=NVars-d;
455  module Ext_1=std(Ext_Our(1,R_std));
456  matrix T=lift(R,R_std);
457  list l=genericity(T);
458  option(set, v);
459  return( control_output( i, NVars, R, Ext_1, l));
460}
461example
462{"EXAMPLE:";echo = 2;
463  //a WindTunnel example
464  ring A = (0,a, omega, zeta, k),(D1, delta),dp;
465  module R;
466  R = [D1+a, -k*a*delta, 0, 0],
467      [0, D1, -1, 0],
468      [0, omega^2, D1+2*zeta*omega, -omega^2];
469  R=transpose(R);
470  view(R);
471  view(controlDim(R));
472};
473//------------------------------------------------------------------------
474proc colrank(module M)
475"USAGE: colrank(M); M a matrix/module
476RETURN: int
477PURPOSE: compute the column rank of M as of matrix
478NOTE: this procedure uses Bareiss algorithm
479"{
480  // NOte continued:
481  // which might not terminate in some cases
482  module M_red  = bareiss(M)[1];
483  int NCols_red = ncols(M_red);
484  return (NCols_red);
485}
486example
487{"EXAMPLE: ";echo = 2;
488  // de Rham complex
489  ring r=0,(D(1..3)),dp;
490  module R;
491  R=[0,-D(3),D(2)],
492    [D(3),0,-D(1)],
493    [-D(2),D(1),0];
494  R=transpose(R);
495  colrank(R);
496};
497
498//------------------------------------------------------------------------
499static proc autonom_output( int i, int NVars, module RC, int R_rank )
500"USAGE:  proc autonom_output(i, NVars, RC, R_rank)
501           i:  integer, number of first nonzero Ext or
502               just number of variables in a base ring + 1 in case that all the Exts are zero
503           NVars:  integer, number of variables in a base ring
504           RC: module, kernel-representation of controllable part of the system
505           R_rank: integer, column rank of the representation matrix
506PURPOSE: compute all the autonomy properties of the system which is to be returned in 'autonom' procedure
507RETURN:  list
508NOTE:  this procedure is used in 'autonom' procedure
509"
510{
511  int d=NVars-i;//that is the dimension of the system
512  string DofS="dimension of the system:";
513  string Fn = "number of first nonzero Ext:";
514  if(i==0)
515  {
516    return( list(  Fn,
517                   i,
518                  "not autonomous",
519                   "kernel representation for controllable part",
520                   RC,
521                   "column rank of the matrix",
522                   R_rank,
523                   DofS,
524                   d )
525          );
526  };
527
528  if( i>NVars )
529  {
530    return( list( Fn,
531                  -1,
532                  "trivial",
533                  DofS,
534                  d )
535          );
536  };
537
538  //
539  //now i<=NVars
540  //
541
542
543  if( i==1 )
544  // in case that NVars==1 there is no sense to consider the notion
545  // of strongly autonomous behavior, because it does not imply
546  // that system is overdetermined in this case
547  {
548    return( list ( Fn,
549                   i,
550                  "autonomous, not overdetermined",
551                   DofS,
552                   d )
553          );
554  };
555
556  if( i==NVars )
557  {
558    return( list(  Fn,
559                   i,
560                  "strongly autonomous(fin. dimensional),in particular overdetermined",
561                   DofS,
562                   d)
563          );
564  };
565
566  if( i<NVars )
567  {
568    return( list ( Fn,
569                   i,
570                  "overdetermined, not strongly autonomous",
571                   DofS,
572                   d)
573          );
574  };
575};
576//--------------------------------------------------------------------------
577proc autonomDim(module R)
578"USAGE:  autonomDim(R);   R a module (R is a matrix of the system of equations which is to be investigated)
579RETURN: list
580PURPOSE: computes the list of all the properties concerning autonomy of the system (behavior), represented by the matrix R
581NOTE:  this procedure is analogous to 'autonom' but uses dimension calculations
582EXAMPLE:  example autonomDim; shows an example
583"
584{
585  int d;
586  int NVars = nvars(basering);
587  module RT = transpose(R);
588  module RC;  //for computation of controllable part if if exists
589  int R_rank = ncols(R);
590  d     = dim_Our( std(RT) );  //this is the dimension of the system
591  int i = NVars-d;  //First non-zero Ext
592  if( d==0 )
593    {
594      RC=leftKernel(rightKernel(R));
595      R_rank=colrank(R);
596    }
597  return( autonom_output(i,NVars,RC,R_rank) );
598}
599example
600{"EXAMPLE:"; echo = 2;
601  // Cauchy1 example
602  ring r=0,(s1,s2,s3,s4),dp;
603  module R= [s1,-s2],
604            [s2, s1],
605            [s3,-s4],
606            [s4, s3];
607  R=transpose(R);
608  view( R );
609  view( autonomDim(R) );
610};
611//----------------------------------------------------------
612proc autonom(module R)
613"USAGE:  autonom(R);   R a module (R is a matrix of the system of equations which is to be investigated)
614RETURN:  list
615PURPOSE: find all the properties concerning autonomy of the system (behavior) represented by the  matrix R
616EXAMPLE: example autonom; shows an example
617"
618{
619  int NVars=nvars(basering);
620  int ExtIsZero;
621  module RT=transpose(R);
622  module RC;
623  int R_rank=ncols(R);
624  ExtIsZero=is_zero_Our(Ext_Our(0,RT));
625  int i=0;
626  while( (ExtIsZero)&&(i<=NVars) )
627  {
628    i++;
629    ExtIsZero = is_zero_Our(Ext_Our(i,RT));
630  };
631  if (i==0)
632  {
633    RC=leftKernel(rightKernel(R));
634    R_rank=colrank(R);
635  }
636  return(autonom_output(i,NVars,RC,R_rank));
637}
638example
639{"EXAMPLE:"; echo = 2;
640  // Cauchy
641  ring r=0,(s1,s2,s3,s4),dp;
642  module R= [s1,-s2],
643            [s2, s1],
644            [s3,-s4],
645            [s4, s3];
646  R=transpose(R);
647  view( R );
648  view( autonom(R) );
649};
650
651
652//----------------------------------------------------------
653proc genericity(matrix M)
654"USAGE:  genericity(M); M is a matrix/module
655RETURN:  list (of strings)
656PURPOSE: determine parametric expressions which have been assumed to be non-zero in the process of computing the Groebner basis
657NOTE: we strongly recommend to switch on the redSB and redTail options;
658@*    the procedure is effective with the lift procedure for modules with parameters
659EXAMPLE:  example genericity; shows an example
660"
661{
662  // returns "-", if there are no parameters!
663  if (npars(basering)==0)
664  {
665    return("-");
666  }
667  list RT = evas_genericity(M); // list of strings
668  if ((size(RT)==1) && (RT[1] == ""))
669  {
670    return("-");
671  }
672  return(RT);
673}
674example
675{  // TwoPendula
676  "EXAMPLE:"; echo = 2;
677  ring r=(0,m1,m2,M,g,L1,L2),Dt,dp;
678  module RR =
679    [m1*L1*Dt^2, m2*L2*Dt^2, -1, (M+m1+m2)*Dt^2],
680    [m1*L1^2*Dt^2-m1*L1*g, 0, 0, m1*L1*Dt^2],
681    [0, m2*L2^2*Dt^2-m2*L2*g, 0, m2*L2*Dt^2];
682  module R = transpose(RR);
683  module SR = std(R);
684  matrix T = lift(R,SR);
685  genericity(T);
686  //-- The result might be different when computing reduced bases:
687  matrix T2;
688  option(redSB);
689  option(redTail);
690  module SR2 = std(R);
691  T2 =  lift(R,SR2);
692  genericity(T2);
693}
694//---------------------------------------------------------------
695static proc victors_genericity(matrix M)
696{
697  // returns "-", if there are no parameters!
698  if (npars(basering)==0)
699  {
700    return("-");
701  }
702  int plevel = printlevel-voice+2;
703  // M is a matrix over a ring with params and vars;
704  ideal I = ideal(M); // a list of entries
705  I = simplify(I,2); // delete 0's
706  // decompose every coeff in every poly
707  int i;
708  int s = size(I);
709  ideal NM;
710  poly p;
711  number num;
712  int  cl=1;
713  intvec ZeroVec; ZeroVec[nvars(basering)] = 0;
714  intvec W;
715  ideal Numero, Denomiro;
716  int cNu=0; int cDe=0;
717  for (i=1; i<=s; i++)
718  {
719    // remove contents and add them as polys
720    p   = I[i];
721    W   = leadexp(p);
722    if (W == ZeroVec) // i.e. just a coef
723    {
724      num    = denominator(leadcoef(p)); // from poly.lib
725      NM[cl] = numerator(leadcoef(p));
726      dbprint(p,"numerator:");
727      dbprint(p, string(NM[cl]));
728      cNu++; Numero[cNu]= NM[cl];
729      cl++;
730      NM[cl] = num; // denominator
731      dbprint(p,"denominator:");
732      dbprint(p, string(NM[cl]));
733      cDe++; Denomiro[cDe]= NM[cl];
734      cl++;
735      p = p - lead(p); // for the next cycle
736    }
737    if ( p!= 0)
738    {
739      num = content(p);
740      p   = p/num;
741      NM[cl] = denominator(num);
742      dbprint(p,"content denominator:");
743      dbprint(p, string(NM[cl]));
744      cNu++; Numero[cNu]= NM[cl];
745      cl++;
746      NM[cl] = numerator(num);
747      dbprint(p,"content numerator:");
748      dbprint(p, string(NM[cl]));
749      cDe++; Denomiro[cDe]= NM[cl];
750      cl++;
751    }
752    // it seems that the next elements will not have real influence
753    while( p != 0)
754    {
755      NM[cl] = leadcoef(p); // should be all integer, i.e. non-rational
756      dbprint(p,"coef:");
757      dbprint(p, string(NM[cl]));
758      cl++;
759      p = p - lead(p);
760    }
761  }
762  NM = simplify(NM,4); // delete identical
763  string newvars = parstr(basering);
764  def save = basering;
765  string NewRing = "ring @NR =" +string(char(basering))+",("+newvars+"),Dp;";
766  execute(NewRing);
767  // get params as variables
768  // create a list of non-monomials
769  ideal @L;
770  ideal F;
771  ideal NM = imap(save,NM);
772  NM = simplify(NM,8); //delete multiples
773  poly p,q;
774  cl = 1;
775  int j, cf;
776  for(i=1; i<=size(NM);i++)
777  {
778    p = NM[i] - lead(NM[i]);
779    if (p!=0)
780    {
781      //      L[cl] = p;
782      F  = factorize(NM[i],1); //non-constant factors only
783      cf = 1;
784      // factorize every polynomial
785      // throw away every monomial from factorization (also constants from above ring)
786      for (j=1; j<=size(F);j++)
787      {
788        q = F[j]-lead(F[j]);
789        if (q!=0)
790        {
791          @L[cl] = F[j];
792          cl++;
793        }
794      }
795    }
796  }
797  // return the result [in string-format]
798  @L = simplify(@L,2+4+8); // skip zeroes, doubled and entries, diff. by a constant
799  list SL;
800  for (j=1; j<=size(@L);j++)
801  {
802    SL[j] = string(@L[j]);
803  }
804  setring save;
805  return(SL);
806}
807//---------------------------------------------------------------
808static proc evas_genericity(matrix M)
809{
810  // called from the main genericity proc
811  ideal I = ideal(M);
812  I = simplify(I,2+4);
813  int s = size(I);
814  ideal Den;
815  poly p;
816  int i;
817  for (i=1; i<=s; i++)
818  {
819    p = I[i];
820    while (p !=0)
821    {
822      Den = Den, denominator(leadcoef(p));
823      p   = p-lead(p);
824    }
825  }
826  Den = simplify(Den,2+4);
827  string newvars = parstr(basering);
828  def save = basering;
829  string NewRing = "ring @NR =" +string(char(basering))+",("+newvars+"),Dp;";
830  execute(NewRing);
831  ideal F;
832  ideal Den = imap(save,Den);
833  Den = simplify(Den,2);
834  int s1 = size(Den);
835  for (i=1; i<=s1; i++)
836  {
837    if (Den[i] !=1)
838    {
839      F= F, factorize(Den[i],1);
840    }
841  }
842  F = simplify(F, 2+4+8);
843  ideal @L = F;
844  list SL;
845  int c,j;
846  string Mono;
847  c = 1;
848  for (j=1; j<=size(@L);j++)
849  {
850    if (leadcoef(@L[j]) <0)
851    {
852      @L[j] = -1*@L[j];
853    }
854    if ( (@L[j] - lead(@L[j]))==0 ) //@L[j] is a monomial
855    {
856      Mono = Mono + string(@L[j])+ ","; // concatenation
857    }
858    else
859    {
860      c++;
861      SL[c] = string(@L[j]);
862    }
863  }
864  if (Mono!="")
865  {
866    Mono = Mono[1..size(Mono)-1]; // delete the last semicolon
867  }
868  SL[1] = Mono;
869  setring save;
870  return(SL);
871}
872
873//---------------------------------------------------------------
874proc canonize(list L)
875"USAGE:  canonize(L); L a list
876RETURN:  list
877PURPOSE: modules in the list are canonized by computing their reduced minimal (= unique up to constant factor w.r.t. the given ordering) Groebner bases
878ASSUME:  L is the output of control/autonomy procedures
879EXAMPLE:  example canonize; shows an example
880"
881{
882  list M = L;
883  intvec v=Opt_Our();
884  int s = size(L);
885  int i;
886  for (i=2; i<=s; i=i+2)
887  {
888    if (typeof(M[i])=="module")
889    {
890      M[i] = std(M[i]);
891      //      M[i] = prune(M[i]); // mimimal embedding: no need yet
892      //      M[i] = std(M[i]);
893    }
894  }
895  option(set, v); //set old values back
896  return(M);
897}
898example
899{  // TwoPendula with L1=L2=L
900  "EXAMPLE:"; echo = 2;
901  ring r=(0,m1,m2,M,g,L),Dt,dp;
902  module RR =
903    [m1*L*Dt^2, m2*L*Dt^2, -1, (M+m1+m2)*Dt^2],
904    [m1*L^2*Dt^2-m1*L*g, 0, 0, m1*L*Dt^2],
905    [0, m2*L^2*Dt^2-m2*L*g, 0, m2*L*Dt^2];
906  module R = transpose(RR);
907  list C = control(R);
908  list CC = canonize(C);
909  view(CC);
910}
911
912//----------------------------------------------------------------
913
914static proc elementof (int i, intvec v)
915{
916  int b=0;
917  for(int j=1;j<=nrows(v);j++)
918    {
919      if(v[j]==i)
920        {
921          b=1;
922          return (b);
923        }
924    }
925  return (b);
926}
927//-----------------------------------------------------------------
928proc iostruct(module R)
929"USAGE: iostruct( R ); R a module
930RETURN:  list L with entries: string s, intvec v, module P and module Q
931PURPOSE:  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
932NOTE:  the procedure uses Bareiss algorithm
933EXAMPLE:  example iostruct; shows an example
934"
935{
936  // NOTE cont'd
937  //which might not terminate in some cases
938  list L = bareiss(R);
939  int R_rank = ncols(L[1]);
940  int NCols=ncols(R);
941  intvec v=L[2];
942  int temp;
943  int NRows=nrows(v);
944  int i,j;
945  int b=1;
946  module P;
947  module Q;
948  int n=0;
949
950  while(b==1)               //sort v through bubblesort
951    {
952      b=0;
953      for(i=1;i<NRows;i++)
954        {
955          if(v[i]>v[i+1])
956          {
957            temp=v[i];
958            v[i]=v[i+1];
959            v[i+1]=temp;
960            b=1;
961          }
962        }
963    }
964  P=R[v];                     //generate P
965  for(i=1;i<=NCols;i++)       //generate Q
966    {
967      if(elementof(i,v)==1)
968        {
969          i++;
970          continue;
971        }
972      Q=Q,R[i];
973    }
974  Q=simplify(Q,2);
975  string s="The following components have been chosen as outputs: ";
976  return (list(s,v,P,Q));
977}
978example
979{"EXAMPLE:";echo = 2;
980 //Example Antenna
981 ring r = (0, K1, K2, Te, Kp, Kc),(Dt, delta), (c,dp);
982 module RR;
983 RR =
984   [Dt, -K1, 0, 0, 0, 0, 0, 0, 0],
985   [0, Dt+K2/Te, 0, 0, 0, 0, -Kp/Te*delta, -Kc/Te*delta, -Kc/Te*delta],
986   [0, 0, Dt, -K1, 0, 0, 0, 0, 0],
987   [0, 0, 0, Dt+K2/Te, 0, 0, -Kc/Te*delta, -Kp/Te*delta, -Kc/Te*delta],
988   [0, 0, 0, 0, Dt, -K1, 0, 0, 0],
989   [0, 0, 0, 0, 0, Dt+K2/Te, -Kc/Te*delta, -Kc/Te*delta, -Kp/Te*delta];
990 module R = transpose(RR);
991 view(iostruct(R));
992};
993
994//---------------------------------------------------------------
995static proc smdeg(matrix N)
996"USAGE: smdeg( N ); N a matrix
997RETURN:  intvec
998PURPOSE: returns an intvec of length 2 with the index of an element of N with smallest degree
999"
1000{
1001  int n = nrows(N);
1002  int m = ncols(N);
1003  int d,d_temp;
1004  intvec v;
1005  int i,j;            // counter
1006
1007  if (N==0)
1008  {
1009    v = 1,1;
1010    return(v);
1011  }
1012
1013  for (i=1; i<=n; i++)
1014// hier wird ein Element ausgewaehlt(!=0) und mit dessen Grad gestartet
1015  {
1016    for (j=1; j<=m; j++)
1017    {
1018      if( deg(N[i,j])!=-1 )
1019      {
1020        d=deg(N[i,j]);
1021        break;
1022      }
1023    }
1024    if (d != -1)
1025    {
1026      break;
1027    }
1028  }
1029  for(i=1; i<=n; i++)
1030  {
1031    for(j=1; j<=m; j++)
1032    {
1033      d_temp = deg(N[i,j]);
1034      if ( (d_temp < d) && (N[i,j]!=0) )
1035      {
1036        d=d_temp;
1037      }
1038    }
1039  }
1040  for (i=1; i<=n; i++)
1041  {
1042    for (j=1; j<=m;j++)
1043    {
1044      if ( (deg(N[i,j]) == d) && (N[i,j]!=0) )
1045      {
1046        v = i,j;
1047        return(v);
1048      }
1049    }
1050  }
1051}
1052//---------------------------------------------------------------
1053static proc NoNon0Pol(vector v)
1054"USAGE: NoNon0Pol(v), v a vector
1055RETURN:  int
1056PURPOSE: returns 1, if there is only one non-zero element in v and 0 else
1057"{
1058  int i,j;
1059  int n = nrows(v);
1060  for( j=1; j<=n; j++)
1061  {
1062    if (v[j] != 0)
1063    {
1064      i++;
1065    }
1066  }
1067  if ( i!=1 )
1068  {
1069    i=0;
1070  }
1071  return(i);
1072}
1073//---------------------------------------------------------------
1074static proc extgcd_Our(poly p, poly q)
1075{
1076  ideal J;   //for extgcd-computations
1077  matrix T; //----------"------------
1078  list L;
1079  // the extgcd-command has a bug in versions before 2-0-7
1080  if ( system("version")<=2006 )
1081  {
1082    J = p,q; // J = N[k-1,k-1],N[k,k]; //J is of type ideal
1083    L[1] = liftstd(J,T);  //T is of type matrix
1084    if(J[1]==p) //this is just for the case the SINGULAR swaps the
1085    //      two elements due to ordering
1086    {
1087      L[2] = T[1,1];
1088      L[3] = T[2,1];
1089    }
1090    else
1091    {
1092      L[2] = T[2,1];
1093      L[3] = T[1,1];
1094    }
1095  }
1096  else
1097  {
1098    L=extgcd(p,q);
1099    //    L=extgcd(N[k-1,k-1],N[k,k]);
1100    //one can use this line if extgcd-bug is fixed
1101  }
1102  return(L);
1103}
1104static proc normalize_Our(matrix N, matrix Q)
1105"USAGE: normalize_Our(N,Q), N, Q are two matrices
1106PURPOSE: normalizes N and divides the columns of Q through the leading coefficients of the columns of N
1107RETURN: 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
1108NOTE: number of columns of N and Q must coincide.
1109"
1110{
1111  if(ncols(N) != ncols(Q))
1112    {
1113      return (N,Q);
1114    }
1115  module M = module(N);
1116  module S = module(Q);
1117  int NCols = ncols(N);
1118  number n;
1119  for(int i=1;i<=NCols;i++)
1120    {
1121      n = leadcoef(M[i]);
1122      if( n != 0 )
1123        {
1124          M[i]=M[i]/n;
1125          S[i]=S[i]/n;
1126        }
1127     }
1128   N = matrix(M);
1129   Q = matrix(S);
1130   return (N,Q);
1131}
1132
1133//---------------------------------------------------------------
1134proc smith( module M )
1135"USAGE: smith(M); M a module/matrix
1136PURPOSE: computes the Smith normal form of a matrix
1137RETURN: a list of length 4 with the following entries:
1138@*      [1]: the Smith normal form S of M,
1139@*      [2]: the rank of M,
1140@*      [3]: a unimodular matrix U,
1141@*      [4]: a unimodular matrix V,
1142such that U*M*V=S. An warning is returned when no Smith form exists.
1143NOTE: The Smith form only exists over PIDs (principal ideal domains). Use global ordering for computations!
1144"
1145{
1146  if (nvars(basering)>1) //if more than one variable, return empty list
1147  {
1148    string s="The Smith-Form only exists for principal ideal domains";
1149    return (s);
1150  }
1151  matrix N = matrix(M);         //Typecasting
1152  int n = nrows(N);
1153  int m = ncols(N);
1154  matrix P = unitmat(n);       //left transformation matrix
1155  matrix Q = unitmat(m);       //right transformation matrix
1156  int k, i, j, deg_temp;
1157  poly tmp;
1158  vector v;
1159  list L;                      //for extgcd-computation
1160  intmat f[1][n];              //to save degrees
1161  matrix lambda[1][n];         //to save leadcoefficients
1162  intmat g[1][m];              //to save degrees
1163  matrix mu[1][m];             //to save leadcoefficients
1164  int ii;                       //counter
1165
1166  while ((k!=n) && (k!=m) )
1167  {
1168    k++;
1169    while ((k<=n) && (k<=m))  //outer while-loop for column-operations
1170    {
1171      while(k<=m )        //inner while-loop for row-operations
1172      {
1173        if( (n>m) && (k < n) && (k<m))
1174        {
1175          if( simplify((ideal(submat(N,k+1..n,k+1..m))),2)== 0)
1176          {
1177            return(N,k-1,P,Q);
1178          }
1179        }
1180        i,j = smdeg(submat(N,k..n,k..m)); //choose smallest degree in the remaining submatrix
1181        i=i+(k-1);                        //indices adjusted to the whole matrix
1182        j=j+(k-1);
1183        if(i!=k)                    //take the element with smallest degree in the first position
1184        {
1185          N=permrow(N,i,k);
1186          P=permrow(P,i,k);
1187        }
1188        if(j!=k)
1189        {
1190          N=permcol(N,j,k);
1191          Q=permcol(Q,j,k);
1192        }
1193        if(NoNon0Pol(N[k])==1)
1194        {
1195          break;
1196        }
1197        tmp=leadcoef(N[k,k]);
1198        deg_temp=ord(N[k,k]);             //ord outputs the leading degree of N[k,k]
1199        for(ii=k+1;ii<=n;ii++)
1200        {
1201          lambda[1,ii]=leadcoef(N[ii,k])/tmp;
1202          f[1,ii]=deg(N[ii,k])-deg_temp;
1203        }
1204        for(ii=k+1;ii<=n;ii++)
1205        {
1206          N = addrow(N,k,-lambda[1,ii]*var(1)^f[1,ii],ii);
1207          P = addrow(P,k,-lambda[1,ii]*var(1)^f[1,ii],ii);
1208          N,Q=normalize_Our(N,Q);
1209        }
1210      }
1211      if (k>n)
1212      {
1213        break;
1214      }
1215      if(NoNon0Pol(transpose(N)[k])==1)
1216      {
1217        break;
1218      }
1219      tmp=leadcoef(N[k,k]);
1220      deg_temp=ord(N[k,k]); //ord outputs the leading degree of N[k][k]
1221
1222      for(ii=k+1;ii<=m;ii++)
1223      {
1224        mu[1,ii]=leadcoef(N[k,ii])/tmp;
1225        g[1,ii]=deg(N[k,ii])-deg_temp;
1226      }
1227      for(ii=k+1;ii<=m;ii++)
1228      {
1229        N=addcol(N,k,-mu[1,ii]*var(1)^g[1,ii],ii);
1230        Q=addcol(Q,k,-mu[1,ii]*var(1)^g[1,ii],ii);
1231        N,Q=normalize_Our(N,Q);
1232      }
1233    }
1234    if( (k!=1) && (k<n) && (k<m) )
1235    {
1236      L = extgcd_Our(N[k-1,k-1],N[k,k]);
1237      if ( N[k-1,k-1]!=L[1] )  //means that N[k-1,k-1] is not a divisor of N[k,k]
1238      {
1239        N=addrow(N,k-1,L[2],k);
1240        P=addrow(P,k-1,L[2],k);
1241        N,Q=normalize_Our(N,Q);
1242
1243        N=addcol(N,k,-L[3],k-1);
1244        Q=addcol(Q,k,-L[3],k-1);
1245        N,Q=normalize_Our(N,Q);
1246        k=k-2;
1247      }
1248    }
1249  }
1250  if( (k<=n) && (k<=m) )
1251  {
1252    if( N[k,k]==0)
1253    {
1254      return(N,k-1,P,Q);
1255    }
1256  }
1257  return(N,k,P,Q);
1258}
1259example
1260{
1261  "EXAMPLE:";echo = 2;
1262  option(redSB);
1263  option(redTail);
1264  ring r   = 0,x,dp;
1265  module M = [x2,x,3x3-4], [2x2-1,4x,5x2], [2x5,3x,4x];
1266  print(M);
1267  list P = smith(M);
1268  print(P[1]);
1269  matrix N = matrix(M);
1270  matrix B = P[3]*N*P[4];
1271  print(B);
1272}
1273// see what happens when the matrix is already in Smith-Form
1274//  module M = [x,0,0],[0,x2,0],[0,0,x3];
1275//  list L = smith(M);
1276// print(L[1]);
1277//matrix N=matrix(M);
1278//matrix B=L[3]*N*L[4];
1279//print(B);
1280//---------------------------------------------------------------
1281static proc list_tex(L, string name,link l,int nr_loop)
1282"USAGE: list_tex(L,name,l), where L is a list, name a string, l a link
1283         writes the content of list L in a tex-file 'name'
1284RETURN: nothing
1285"
1286{
1287  if(typeof(L)!="list")  //in case L is not a list
1288  {
1289    texobj(name,L);
1290  }
1291  if(size(L)==0)
1292  {
1293  }
1294  else
1295  {
1296    string t;
1297    for (int i=1;i<=size(L);i++)
1298    {
1299      while(1)
1300      {
1301        if(typeof(L[i])=="string")  //Fehler hier fuer normalen output->nur wenn string in liste dann verbatim
1302        {
1303          t=L[i];
1304          if(nr_loop==1)
1305          {
1306            write(l,"\\begin\{center\}");
1307            write(l,"\\begin\{verbatim\}");
1308          }
1309          write(l,t);
1310          if(nr_loop==0)
1311          {
1312            write(l,"\\par");
1313          }
1314          if(nr_loop==1)
1315          {
1316            write(l,"\\end\{verbatim\}");
1317            write(l,"\\end\{center\}");
1318          }
1319          break;
1320        }
1321        if(typeof(L[i])=="module")
1322        {
1323          texobj(name,matrix(L[i]));
1324          break;
1325        }
1326        if(typeof(L[i])=="list")
1327        {
1328          list_tex(L[i],name,l,1);
1329          break;
1330        }
1331        write(l,"\\begin\{center\}");
1332        texobj(name,L[i]);
1333        write(l,"\\end\{center\}");
1334        write(l,"\\par");
1335        break;
1336      }
1337    }
1338  }
1339}
1340example
1341{
1342  "EXAMPLE:";echo = 2;
1343}
1344//---------------------------------------------------------------
1345proc verbatim_tex(string s, link l)
1346"USAGE: verbatim_tex(s,l), where s is a string and l a link
1347PURPOSE: writes the content of s in verbatim-environment in the file
1348         specified by link
1349RETURN: nothing
1350"
1351{
1352  write(l,"\\begin{verbatim}");
1353  write(l,s);
1354  write(l,"\\end{verbatim}");
1355  write(l,"\\par");
1356}
1357example
1358{
1359  "EXAMPLE:";echo = 2;
1360}
1361//---------------------------------------------------------------
1362proc findTorsion(module R, ideal TAnn)
1363"USAGE:  findTorsion(R, I);   R an ideal/matrix/module, I an ideal
1364RETURN:  module
1365PURPOSE: computes the Groebner basis of the submodule of R, annihilated by I
1366NOTE: 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
1367the submodule of R
1368EXAMPLE: example findTorsion; shows an example
1369"
1370{
1371  // motivation: let R be a module,
1372  // TAnn is the annihilator of t(R)\subset R
1373  // compute the generators of t(R) explicitly
1374  ideal AS = TAnn;
1375  module S = R;
1376  if (attrib(S,"isSB")<>1)
1377  {
1378    S = std(S);
1379  }
1380  if (attrib(AS,"isSB")<>1)
1381  {
1382    AS = std(AS);
1383  }
1384  int nc  = ncols(S);
1385  module To = quotient(S,AS);
1386  To = std(NF(To,S));
1387  return(To);
1388}
1389example
1390{
1391  "EXAMPLE:";echo = 2;
1392  // Flexible Rod
1393  ring A = 0,(D1, D2), (c,dp);
1394  module R= [D1, -D1*D2, -1], [2*D1*D2, -D1-D1*D2^2, 0];
1395  module RR = transpose(R);
1396  list L = control(RR);
1397  // here, we have the annihilator:
1398  ideal LAnn = D1; // = L[10]
1399  module Tr  = findTorsion(RR,LAnn);
1400  print(RR);  // the module itself
1401  print(Tr); // generators of the torsion submodule
1402}
1403
1404
1405proc controlExample(string s)
1406"USAGE:  controlExample(s);   s a string
1407RETURN:  ring
1408PURPOSE: set up an example from the mini database by initalizing a ring and a module in a ring
1409NOTE: in order to see the list of available examples, execute @code{controlExample(\"show\");}
1410@* 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
1411@*  @code{def A = controlExample(\"Antenna\");} and @code{setring A;},
1412@* A will become a basering from the example \"Antenna\" with
1413the predefined system module R (transposed).
1414After that one can just execute @code{control(R);} respectively
1415@code{autonom(R);} to perform the control resp. autonomy analysis of R.
1416EXAMPLE: example controlExample; shows an example
1417"{
1418  list E, S, D; // E=official name, S=synonym, D=description
1419  E[1] = "Cauchy1";  S[1] = "cauchy1";  D[1] = "1-dimensional Cauchy equation";
1420  E[2] = "Cauchy2";  S[2] = "cauchy2";  D[2] = "2-dimensional Cauchy equation";
1421  E[3] = "Control1"; S[3] = "control1"; D[3] = "example of a simple noncontrollable system";
1422  E[4] = "Control2"; S[4] = "control2"; D[4] = "example of a simple controllable system";
1423  E[5] = "Antenna";  S[5] = "antenna";  D[5] = "antenna";
1424  E[6] = "Einstein"; S[6] = "einstein"; D[6] = "Einstein equations in vacuum";
1425  E[7] = "FlexibleRod"; S[7] = "flexible rod"; D[7] = "flexible rod";
1426  E[8] = "TwoPendula";  S[8] = "two pendula";  D[8] = "two pendula mounted on a cart";
1427  E[9] = "WindTunnel";  S[9] = "wind tunnel";D[9] = "wind tunnel";
1428  E[10] = "Zerz1";      S[10] = "zerz1"; D[10] = "example from the lecture of Eva Zerz";
1429  // all the examples so far
1430  int i;
1431  if ( (s=="show") || (s=="Show") )
1432  {
1433    print("The list of examples:");
1434    for (i=1; i<=size(E); i++)
1435    {
1436      printf("name: %s,  desc: %s", E[i],D[i]);
1437    }
1438    return();
1439  }
1440  string t;
1441  for (i=1; i<=size(E); i++)
1442  {
1443    if ( (s==E[i]) || (s==S[i]) )
1444    {
1445      t = "def @A = ex"+E[i]+"();";
1446      execute(t);
1447      return(@A);
1448    }
1449  }
1450  "No example found";
1451  return();
1452}
1453example
1454{
1455  "EXAMPLE:";echo = 2;
1456  controlExample("show");   // let us see all available examples:
1457  def B = controlExample("TwoPendula"); // let us set up a particular example
1458  setring B;
1459  print(R);
1460}
1461
1462//----------------------------------------------------------
1463//
1464//Some example rings with defined systems
1465//----------------------------------------------------------
1466//autonomy:
1467//
1468//----------------------------------------------------------
1469static proc exCauchy1()
1470{
1471  ring @r=0,(s1,s2),dp;
1472  module R= [s1,-s2],
1473            [s2, s1];
1474  R=transpose(R);
1475  export R;
1476  return(@r);
1477};
1478//----------------------------------------------------------
1479static proc exCauchy2()
1480{
1481  ring @r=0,(s1,s2,s3,s4),dp;
1482  module R= [s1,-s2],
1483            [s2, s1],
1484            [s3,-s4],
1485            [s4, s3];
1486  R=transpose(R);
1487  export R;
1488  return(@r);
1489};
1490//----------------------------------------------------------
1491static proc exZerz1()
1492{
1493  ring @r=0,(d1,d2),dp;
1494  module R=[d1^2-d2],
1495           [d2^2-1];
1496  R=transpose(R);
1497  export R;
1498  return(@r);
1499};
1500//----------------------------------------------------------
1501//control
1502//----------------------------------------------------------
1503static proc exControl1()
1504{
1505  ring @r=0,(s1,s2,s3),dp;
1506  module R=[0,-s3,s2],
1507           [s3,0,-s1];
1508  R=transpose(R);
1509  export R;
1510  return(@r);
1511};
1512//----------------------------------------------------------
1513static proc exControl2()
1514{
1515  ring @r=0,(s1,s2,s3),dp;
1516  module R=[0,-s3,s2],
1517           [s3,0,-s1],
1518           [-s2,s1,0];
1519  R=transpose(R);
1520  export R;
1521  return(@r);
1522};
1523//----------------------------------------------------------
1524static proc exAntenna()
1525{
1526  ring @r = (0, K1, K2, Te, Kp, Kc),(Dt, delta), dp;
1527  module R;
1528  R = [Dt, -K1, 0, 0, 0, 0, 0, 0, 0],
1529      [0, Dt+K2/Te, 0, 0, 0, 0, -Kp/Te*delta, -Kc/Te*delta, -Kc/Te*delta],
1530      [0, 0, Dt, -K1, 0, 0, 0, 0, 0],
1531      [0, 0, 0, Dt+K2/Te, 0, 0, -Kc/Te*delta, -Kp/Te*delta, -Kc/Te*delta],
1532      [0, 0, 0, 0, Dt, -K1, 0, 0, 0],
1533      [0, 0, 0, 0, 0, Dt+K2/Te, -Kc/Te*delta, -Kc/Te*delta, -Kp/Te*delta];
1534
1535  R=transpose(R);
1536  export R;
1537  return(@r);
1538};
1539
1540//----------------------------------------------------------
1541
1542static proc exEinstein()
1543{
1544  ring @r = 0,(D(1..4)),dp;
1545  module R =
1546  [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)],
1547  [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],
1548  [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],
1549  [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)],
1550  [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)],
1551  [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],
1552  [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)],
1553  [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)],
1554  [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)],
1555  [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];
1556
1557  R=transpose(R);
1558  export R;
1559  return(@r);
1560};
1561
1562//----------------------------------------------------------
1563static proc exFlexibleRod()
1564{
1565  ring @r = 0,(D1, delta), dp;
1566  module R;
1567  R = [D1, -D1*delta, -1], [2*D1*delta, -D1-D1*delta^2, 0];
1568
1569  R=transpose(R);
1570  export R;
1571  return(@r);
1572};
1573
1574//----------------------------------------------------------
1575static proc exTwoPendula()
1576{
1577  ring @r=(0,m1,m2,M,g,L1,L2),Dt,dp;
1578  module R = [m1*L1*Dt^2, m2*L2*Dt^2, -1, (M+m1+m2)*Dt^2],
1579             [m1*L1^2*Dt^2-m1*L1*g, 0, 0, m1*L1*Dt^2],
1580             [0, m2*L2^2*Dt^2-m2*L2*g, 0, m2*L2*Dt^2];
1581
1582  R=transpose(R);
1583  export R;
1584  return(@r);
1585};
1586//----------------------------------------------------------
1587static proc exWindTunnel()
1588{
1589  ring @r = (0,a, omega, zeta, k),(D1, delta),dp;
1590  module R = [D1+a, -k*a*delta, 0, 0],
1591             [0, D1, -1, 0],
1592             [0, omega^2, D1+2*zeta*omega, -omega^2];
1593
1594  R=transpose(R);
1595  export R;
1596  return(@r);
1597};
Note: See TracBrowser for help on using the repository browser.