# source:git/Singular/LIB/matrix.lib@5dc4ea

spielwiese
Last change on this file since 5dc4ea was 5dc4ea, checked in by Hans Schönemann <hannes@…>, 26 years ago
* hannes: changes to naLcm, naNormalize * greuel/hannes: changes to deform.lib invar.lib(Header) matrix.lib prim_dec.lib primdec.lib git-svn-id: file:///usr/local/Singular/svn/trunk@730 2c84dea3-7e68-4137-9b89-c4e89433aadc
• Property mode set to `100644`
File size: 18.2 KB
Line
1// \$Id: matrix.lib,v 1.4 1997-09-18 09:58:24 Singular Exp \$
3///////////////////////////////////////////////////////////////////////////////
4LIBRARY:  matrix.lib    PROCEDURES FOR MATRIX OPERATIONS
5
6 compress(A);           matrix, zero columns from A deleted
7 concat(A1,A2,..);      matrix, concatenation of matrices A1,A2,...
8 diag(p,n);             matrix, nxn diagonal matrix with entries poly p
9 dsum(A1,A2,..);        matrix, direct sum of matrices A1,A2,...
10 flatten(A);            ideal, generated by entries of matrix A
11 genericmat(n,m[,id]);  generic nxm matrix [entries from id]
12 is_complex(c);         1 if list c is a complex, 0 if not
13 outer(A,B);            matrix, outer product of matrices A and B
14 power(A,n);            matrix/intmat, n-th power of matrix/intmat A
15 skewmat(n[,id]);       generic skew-symmetric nxn matrix [entries from id]
16 submat(A,r,c);         submatrix of A with rows/cols specified by intvec r/c
17 symmat(n[,id]);        generic symmetric nxn matrix [entries from id]
18 tensor(A,B);           matrix, tensor product of matrices A nd B
19 unitmat(n);            unit square matrix of size n
20 gauss_col(A);          transform constant matrix A into col-reduced nf
21 gauss_row(A);          transform constant matrix A into row-reduced nf
22 addcol(A,c1,p,c2);     add p*(c1-th col) to c2-th column of matrix A, p poly
23 addrow(A,r1,p,r2);     add p*(r1-th row) to r2-th row of matrix A, p poly
24 multcol(A,c,p);        multiply c-th column of A with poly p
25 multrow(A,r,p);        multiply r-th row of A with poly p
26 permcol(A,i,j);        permute i-th and j-th columns
27 permrow(A,i,j);        permute i-th and j-th rows
28           (parameters in square brackets [] are optional)
29
30LIB "inout.lib";
31LIB "ring.lib";
32LIB "random.lib";
33///////////////////////////////////////////////////////////////////////////////
34
35proc compress (A)
36USAGE:   compress(A); A matrix/ideal/module/intmat/intvec
37RETURN:  same type, zero columns/generators from A deleted
38         (in an intvec zero elements are deleted)
39EXAMPLE: example compress; shows an example
40{
41   if( typeof(A)=="matrix" ) { return(matrix(simplify(A,2))); }
42   if( typeof(A)=="intmat" or typeof(A)=="intvec" )
43   {
44      ring r=0,x,lp;
45      if( typeof(A)=="intvec" ) { intmat C=transpose(A); kill A; intmat A=C; }
46      module m = matrix(A);
47      intmat B[nrows(A)][size(m)];
48      int i,j;
49      for( i=1; i<=ncols(A); i=i+1 )
50      {
51         if( m[i]!=[0] )
52         {
53            j=j+1;
54            B[1..nrows(A),j]=A[1..nrows(A),i];
55         }
56      }
57      if( defined(C) ) { return(intvec(B)); }
58      return(B);
59    }
60   return(simplify(A,2));
61}
62example
63{ "EXAMPLE:"; echo = 2;
64   ring r=0,(x,y,z),ds;
65   matrix A[3][4]=1,0,3,0,x,0,z,0,x2,0,z2,0;
66   print(A);
67   print(compress(A));
68   module m=module(A); show(m);
69   show(compress(m));
70   intmat B[3][4]=1,0,3,0,4,0,5,0,6,0,7,0;
71   compress(B);
72   intvec C=0,0,1,2,0,3;
73   compress(C);
74}
75////////////////////////////////////////////////////////////////////////////////
76proc concat (list #)
77USAGE:   concat(A1,A2,..); A1,A2,... matrices
78RETURN:  matrix, concatenation of A1,A2,... . Number of rows of result matrix is
79         max(nrows(A1),nrows(A2),...)
80EXAMPLE: example concat; shows an example
81{
82   int i;
83   module B=module(#[1]);
84   for( i=2; i<=size(#); i=i+1 ) { B=B,module(#[i]); }
85   return(matrix(B));
86}
87example
88{ "EXAMPLE:"; echo = 2;
89   ring r=0,(x,y,z),ds;
90   matrix A[3][3]=1,2,3,x,y,z,x2,y2,z2;
91   matrix B[2][2]=1,0,2,0; matrix C[1][4]=4,5,x,y;
92   print(A);
93   print(B);
94   print(C);
95   print(concat(A,B,C));
96}
97////////////////////////////////////////////////////////////////////////////////
98
99proc diag (list #)
100USAGE:   diag(p,n); p poly, n integer
101         diag(A);   A matrix
102RETURN:  diag(p,n): diagonal matrix, p times unitmatrix of size n
103         diag(A)  : n*mxn*m diagonal matrix with entries all the entries of the
104                    nxm matrix A, taken from the 1st row, 2nd row etc of A
105EXAMPLE: example diag; shows an example
106{
107   if( size(#)==2 ) { return(matrix(#[1]*freemodule(#[2]))); }
108   if( size(#)==1 )
109   {
110      int i; ideal id=#[1];
111      int n=ncols(id); matrix A[n][n];
112      for( i=1; i<=n; i=i+1 ) { A[i,i]=id[i]; }
113   }
114   return(A);
115}
116example
117{ "EXAMPLE:"; echo = 2;
118   ring r=0,(x,y,z),ds;
119   print(diag(xy,4));
120   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
121   print(A);
122   print(diag(A));
123}
124////////////////////////////////////////////////////////////////////////////////
125
126proc dsum (list #)
127USAGE:   dsum(A1,A2,..); A1,A2,... matrices
128RETURN:  matrix, direct sum of A1,A2,...
129EXAMPLE: example dsum; shows an example
130{
131   int i,N,a;
132   list L;
133   for( i=1; i<=size(#); i=i+1 ) { N=N+nrows(#[i]); }
134   for( i=1; i<=size(#); i=i+1 )
135   {
136      matrix B[N][ncols(#[i])];
137      B[a+1..a+nrows(#[i]),1..ncols(#[i])]=#[i];
138      a=a+nrows(#[i]);
139      L[i]=B; kill B;
140   }
141   return(concat(L));
142}
143example
144{ "EXAMPLE:"; echo = 2;
145   ring r=0,(x,y,z),ds;
146   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
147   matrix B[2][2]=1,x,y,z;
148   matrix C[1][4]=4,5,x,y;
149   print(A);
150   print(B);
151   print(C);
152   print(dsum(A,B,C));
153}
154////////////////////////////////////////////////////////////////////////////////
155
156proc flatten (matrix A)
157USAGE:   flatten(A); A matrix
158RETURN:  ideal, generated by all entries from A
159EXAMPLE: example flatten; shows an example
160{
161   return(ideal(A));
162}
163example
164{ "EXAMPLE:"; echo = 2;
165   ring r=0,(x,y,z),ds;
166   matrix A[3][3]=1,2,3,x,y,z,7,8,9;
167   print(A);
168   flatten(A);
169}
170////////////////////////////////////////////////////////////////////////////////
171
172proc genericmat (int n,int m,list #)
173USAGE:   genericmat(n,m[,id]);  n,m=integers, id=ideal
174RETURN:  nxm matrix, with entries from id (default: id=maxideal(1))
175NOTE:    if id has less than nxm elements, the matrix is filled with 0's,
176         genericmat(n,m); creates the generic nxm matrix
177EXAMPLE: example genericmat; shows an example
178{
179   if( size(#)==0 ) { ideal id=maxideal(1); }
180   if( size(#)==1 ) { ideal id=#[1]; }
181   if( size(#)>=2 ) { "// give 3 arguments, 3-rd argument must be an ideal"; }
182   matrix B[n][m]=id;
183   return(B);
184}
185example
186{ "EXAMPLE:"; echo = 2;
187   ring R=0,x(1..16),lp;
188   print(genericmat(4,4));    // the generic 4x4 matrix
189   changevar("R1",A_Z("a",4),R);
190   matrix A=genericmat(4,5,maxideal(1)^3);
191   print(A);
192   int n,m=4,3;
193   ideal i = ideal(randommat(1,n*m,maxideal(1),9));
194   print(genericmat(n,m,i));  // matrix of generic linear forms
195   kill R1;
196}
197///////////////////////////////////////////////////////////////////////////////
198
199proc is_complex (list c)
200USAGE:   is_complex(c); c = list of size-compatible modules or matrices
201RETURN:  1 if c[i]*c[i+1]=0 for all i, 0 if not.
202NOTE:    Ideals are treated internally as 1-line matrices
203EXAMPLE: example is_complex; shows an example
204{
205   int i;
206   module @test;
207   for( i=1; i<=size(c)-1; i=i+1 )
208   {
209      c[i]=matrix(c[i]); c[i+1]=matrix(c[i+1]);
210      @test=c[i]*c[i+1];
211      if (size(@test)!=0)
212      {
213         if( voice==2 ) { "// argument is not a complex at position",i; }
214         return(0);
215      }
216   }
217   if( voice==2 ) { "// argument is a complex"; }
218   return(1);
219}
220example
221{ "EXAMPLE:";   echo = 2;
222   ring r=32003,(x,y,z),ds;
223   ideal i=x4+y5+z6,xyz,yx2+xz2+zy7;
224   list L=res(i,0);
225   is_complex(L);
226   L[4]=matrix(i);
227   is_complex(L);
228}
229////////////////////////////////////////////////////////////////////////////////
230
231proc outer (matrix A, matrix B)
232USAGE:   outer(A,B); A,B matrices
233RETURN:  matrix, outer product of A and B
234EXAMPLE: example outer; shows an example
235{
236   int i,j; list L;
237   int triv = nrows(B)*ncols(B);
238   if( triv==1 )
239   {
240     return(B[1,1]*A);
241   }
242   else
243   {
244     int N = nrows(A)*nrows(B);
245     matrix C[N][ncols(B)];
246     for( i=1; i<=ncols(A); i=i+1 )
247     {
248       for( j=1; j<=nrows(A); j=j+1 )
249       {
250          C[(j-1)*nrows(B)+1..j*nrows(B),1..ncols(B)]=A[j,i]*B;
251       }
252       L[i]=C;
253     }
254     return(concat(L));
255   }
256}
257example
258{ "EXAMPLE:"; echo = 2;
259   ring r=32003,(x,y,z),ds;
260   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
261   matrix B[2][2]=x,y,0,z;
262   print(A);
263   print(B);
264   print(outer(A,B));
265}
266////////////////////////////////////////////////////////////////////////////////
267
268proc power ( A, int n)
269USAGE:   power(A,n);  A a square-matrix of type intmat or matrix, n=integer
270RETURN:  inmat resp. matrix, the n-th power of A
271NOTE:    for intamt and big n the result may be wrong because of int overflow
272EXAMPLE: example power; shows an example
273{
274//---------------------------- type checking ----------------------------------
275   if( typeof(A)!="matrix" and typeof(A)!="intmat" )
276   {
277      "// no matrix or intmat!";
278      return (A);
279   }
280   if( ncols(A) != nrows(A) )
281   {
282      "// not a suare matrix!";
283      return();
284   }
285//---------------------------- trivial cases ----------------------------------
286   int ii;
287   if( n <= 0 )
288   {
289      if( typeof(A)=="matrix" )
290      {
291         return (unitmat(nrows(A)));
292      }
293      if( typeof(A)=="intmat" )
294      {
295         intmat B[nrows(A)][nrows(A)];
296         for( ii=1; ii<=nrows(A); ii++ )
297         {
298            B[ii,ii] = 1;
299         }
300         return (B);
301      }
302   }
303   if( n == 1 ) { return (A); }
304//---------------------------- sub procedure ----------------------------------
305   proc matpow (A, int n)
306   {
307      def B = A*A;
308      int ii= 2;
309      int jj= 4;
310      while( jj <= n )
311      {
312         B=B*B;
313         ii=jj;
314         jj=2*jj;
315      }
316      return(B,n-ii);
317   }
318//----------------------------- main program ----------------------------------
319   list L = matpow(A,n);
320   def B  = L[1];
321   ii     = L[2];
322   while( ii>=2 )
323   {
324      L = matpow(A,ii);
325      B = B*L[1];
326      ii= L[2];
327   }
328   if( ii == 0) { return(B); }
329   if( ii == 1) { return(A*B); }
330}
331example
332{ "EXAMPLE:"; echo = 2;
333   intmat A[3][3]=1,2,3,4,5,6,7,8,9;
334   print(power(A,3));"";
335   ring r=0,(x,y,z),dp;
336   matrix B[4][4]=0,x,y,z,0,0,y,z,0,0,0,z,x,y,z,0;
337   print(power(B,3));"";
338   matrix C[3][3]=1,2,3,4,5,6,7,8,9;
339   power(C,50);
340}
341////////////////////////////////////////////////////////////////////////////////
342
343proc skewmat (int n, list #)
344USAGE:   skewmat(n[,id]);  n integer, id ideal
345RETURN:  skew-symmetric nxn matrix, with entries from id
346         (default: id=maxideal(1))
347NOTE:    if id has less than n*(n-1)/2 elements, the matrix is filled with 0's,
348         skewmat(n); creates the generic skew-symmetric matrix
349EXAMPLE: example skewmat; shows an example
350{
351   matrix B[n][n];
352   if( size(#)==0 ) { ideal id=maxideal(1); }
353   else { ideal id=#[1]; }
354   id = id,B[1..n,1..n];
355   int i,j;
356   for( i=0; i<=n-2; i=i+1 )
357   {
358      B[i+1,i+2..n]=id[j+1..j+n-i-1];
359      j=j+n-i-1;
360   }
361   matrix A=transpose(B);
362   B=B-A;
363   return(B);
364}
365example
366{ "EXAMPLE:"; echo = 2;
367   ring R=0,x(1..5),lp;
368   print(skewmat(4));    // the generic skew-symmetric matrix
369   changevar("R1",A_Z("a",5),R);
370   matrix A=skewmat(6,maxideal(1)^2);
371   print(A);
372   int n=4;
373   ideal i = ideal(randommat(1,n*(n-1) div 2,maxideal(1),9));
374   print(skewmat(n,i));  // skew matrix of generic linear forms
375   kill R1;
376}
377////////////////////////////////////////////////////////////////////////////////
378
379proc submat (matrix A, intvec r, intvec c)
380USAGE:   submat(A,r,c);  A=matrix, r,c=intvec
381RETURN:  matrix, submatrix of A with rows specified by intvec r and columns
382         specified by intvec c
383EXAMPLE: example submat; shows an example
384{
385   matrix B[size(r)][size(c)]=A[r,c];
386   return(B);
387}
388example
389{ "EXAMPLE:"; echo = 2;
390   ring R=32003,(x,y,z),lp;
391   matrix A[4][4]=x,y,z,0,1,2,3,4,5,6,7,8,9,x2,y2,z2;
392   print(A);
393   intvec v=1,3,4;
394   matrix B=submat(A,v,1..3);
395   print(B);
396}
397////////////////////////////////////////////////////////////////////////////////
398
399proc symmat (int n, list #)
400USAGE:   symmat(n[,id]);  n integer, id ideal
401RETURN:  symmetric nxn matrix, with entries from id (default: id=maxideal(1))
402NOTE:    if id has less than n*(n+1)/2 elements, the matrix is filled with 0's,
403         symmat(n); creates the generic symmetric matrix
404EXAMPLE: example symmat; shows an example
405{
406   matrix B[n][n];
407   if( size(#)==0 ) { ideal id=maxideal(1); }
408   else { ideal id=#[1]; }
409   id = id,B[1..n,1..n];
410   int i,j;
411   for( i=0; i<=n-1; i=i+1 )
412   {
413      B[i+1,i+1..n]=id[j+1..j+n-i];
414      j=j+n-i;
415   }
416   matrix A=transpose(B);
417   for( i=1; i<=n; i=i+1 ) {  A[i,i]=0; }
418   B=A+B;
419   return(B);
420}
421example
422{ "EXAMPLE:"; echo = 2;
423   ring R=0,x(1..10),lp;
424   print(symmat(4));    // the generic symmetric matrix
425   changevar("R1",A_Z("a",5),R);
426   matrix A=symmat(5,maxideal(1)^2);
427   print(A);
428   int n=3;
429   ideal i = ideal(randommat(1,n*(n+1) div 2,maxideal(1),9));
430   print(symmat(n,i));  // symmetric matrix of generic linear forms
431   kill R1;
432}
433////////////////////////////////////////////////////////////////////////////////
434
435proc tensor (matrix A, matrix B)
436USAGE:   tensor(A,B); A,B matrices
437RETURN:  matrix, tensor product of A and B
438EXAMPLE: example tensor; shows an example
439{
440   int i,j;
441   matrix C=B;
442   for( i=2; i<=nrows(A); i=i+1 ) { C=dsum(C,B); }
443   matrix D[nrows(C)][ncols(A)*nrows(B)];
444   for( j=1; j<=nrows(B); j=j+1 )
445   {
446      for( i=1; i<=nrows(A); i=i+1 )
447      {
448         D[(i-1)*nrows(B)+j,(j-1)*ncols(A)+1..j*ncols(A)]=A[i,1..ncols(A)];
449      }
450   }
451   return(concat(C,D));
452}
453example
454{ "EXAMPLE:"; echo = 2;
455   ring r=32003,(x,y,z),(c,ds);
456   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
457   matrix B[2][2]=x,y,0,z;
458   print(A);
459   print(B);
460   print(tensor(A,B));
461}
462////////////////////////////////////////////////////////////////////////////////
463
464proc unitmat (int n)
465USAGE:   unitmat(n);  n integer >= 0
466RETURN:  nxn unit matrix
467NOTE:    needs a basering, diagonal entries are numbers (=1) in the basering
468EXAMPLE: example unitmat; shows an example
469{
470   return(matrix(freemodule(n)));
471}
472example
473{ "EXAMPLE:"; echo = 2;
474   ring r=32003,(x,y,z),lp;
475   print(xyz*unitmat(4));
476   print(unitmat(5));
477}
478///////////////////////////////////////////////////////////////////////////////
479
480proc gauss_col (matrix A)
481USAGE:   gauss_col(A); A=matrix with constant coefficients
482RETURN:  matrix = col-reduced lower-triagonal normal form of A
483NOTE:    the procedure sets the global option-command: option(noredSB);
484EXAMPLE: example gauss_col; shows an example
485{
486   def R=basering;
487   changeord("@R","ds,c",R);
488   option(redSB); option(nointStrategy);
489   matrix A = imap(R,A);
490   A = matrix(std(A),nrows(A),ncols(A));
491   setring R;
492   A=imap(@R,A);
493   option(noredSB);
494   kill @R;
495   return(A);
496}
497example
498{ "EXAMPLE:"; echo = 2;
499   ring S=0,x,dp;
500   matrix A[5][4] =  3, 1,1,-1,
501                    13, 8,6,-7,
502                    14,10,6,-7,
503                     7, 4,3,-3,
504                     2, 1,0, 3;
505   print(gauss_col(A));
506}
507///////////////////////////////////////////////////////////////////////////////
508
509proc gauss_row (matrix A)
510USAGE:   gauss_row(A); A=matrix with constant coefficients
511RETURN:  matrix = row-reduced upper-triangular normal form of A
512NOTE:    may be used to solve a system of linear equations
513         see proc 'linearsolve' from 'solve.lib' for a different method
514         the procedure sets the global option-command: option(noredSB);
515EXAMPLE: example gauss_row; shows an example
516{
517   A = gauss_col(transpose(A));
518   return(transpose(A));
519}
520example
521{ "EXAMPLE:"; echo = 2;
522   ring S=0,x,dp;
523   matrix A[4][5] =  3, 1,1,-1,2,
524                    13, 8,6,-7,1,
525                    14,10,6,-7,1,
526                     7, 4,3,-3,3;
527   print(gauss_row(A));
528}
529////////////////////////////////////////////////////////////////////////////////
530
531proc addcol (matrix A, int c1, poly p, int c2)
532USAGE:   addcol(A,c1,p,c2);  A matrix, p poly, c1, c2 positive integers
533RETURN:  matrix,  A being modified by adding p times column c1 to column c2
534EXAMPLE: example addcol; shows an example
535{
536   A[1..nrows(A),c2]=A[1..nrows(A),c2]+p*A[1..nrows(A),c1];
537   return(A);
538}
539example
540{ "EXAMPLE:"; echo = 2;
541   ring r=32003,(x,y,z),lp;
542   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
543   print(A);
545}
546////////////////////////////////////////////////////////////////////////////////
547
548proc addrow (matrix A, int r1, poly p, int r2)
549USAGE:   addcol(A,r1,p,r2);  A matrix, p poly, r1, r2 positive integers
550RETURN:  matrix,  A being modified by adding p times row r1 to row r2
551EXAMPLE: example addrow; shows an example
552{
553   A[r2,1..ncols(A)]=A[r2,1..ncols(A)]+p*A[r1,1..ncols(A)];
554   return(A);
555}
556example
557{ "EXAMPLE:"; echo = 2;
558   ring r=32003,(x,y,z),lp;
559   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
560   print(A);
562}
563////////////////////////////////////////////////////////////////////////////////
564
565proc multcol (matrix A, int c, poly p)
566USAGE:   addcol(A,c,p);  A matrix, p poly, c positive integer
567RETURN:  matrix,  A being modified by multiplying column c with p
568EXAMPLE: example multcol; shows an example
569{
570   A[1..nrows(A),c]=p*A[1..nrows(A),c];
571   return(A);
572}
573example
574{ "EXAMPLE:"; echo = 2;
575   ring r=32003,(x,y,z),lp;
576   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
577   print(A);
578   print(multcol(A,2,xy));
579}
580////////////////////////////////////////////////////////////////////////////////
581
582proc multrow (matrix A, int r, poly p)
583USAGE:   addcol(A,r,p);  A matrix, p poly, r positive integer
584RETURN:  matrix,  A being modified by multiplying row r with p
585EXAMPLE: example multrow; shows an example
586{
587   A[r,1..ncols(A)]=p*A[r,1..ncols(A)];
588   return(A);
589}
590example
591{ "EXAMPLE:"; echo = 2;
592   ring r=32003,(x,y,z),lp;
593   matrix A[3][3]=1,2,3,4,5,6,7,8,9;
594   print(A);
595   print(multrow(A,2,xy));
596}
597////////////////////////////////////////////////////////////////////////////////
598
599proc permcol (matrix A, int c1, int c2)
600USAGE:   permcol(A,c1,c2);  A matrix, c1,c2 positive integers
601RETURN:  matrix,  A being modified by permuting column c1 and c2
602EXAMPLE: example permcol; shows an example
603{
604   matrix B=A;
605   B[1..nrows(B),c1]=A[1..nrows(A),c2];
606   B[1..nrows(B),c2]=A[1..nrows(A),c1];
607   return(B);
608}
609example
610{ "EXAMPLE:"; echo = 2;
611   ring r=32003,(x,y,z),lp;
612   matrix A[3][3]=1,x,3,4,y,6,7,z,9;
613   print(A);
614   print(permcol(A,2,3));
615}
616////////////////////////////////////////////////////////////////////////////////
617
618proc permrow (matrix A, int r1, int r2)
619USAGE:   permrow(A,r1,r2);  A matrix, r1,r2 positive integers
620RETURN:  matrix,  A being modified by permuting row r1 and r2
621EXAMPLE: example permrow; shows an example
622{
623   matrix B=A;
624   B[r1,1..ncols(B)]=A[r2,1..ncols(A)];
625   B[r2,1..ncols(B)]=A[r1,1..ncols(A)];
626   return(B);
627}
628example
629{ "EXAMPLE:"; echo = 2;
630   ring r=32003,(x,y,z),lp;
631   matrix A[3][3]=1,2,3,x,y,z,7,8,9;
632   print(A);
633   print(permrow(A,2,1));
634}
635////////////////////////////////////////////////////////////////////////////////
Note: See TracBrowser for help on using the repository browser.