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