Changeset db4770 in git


Ignore:
Timestamp:
Jul 8, 1996, 10:22:51 AM (28 years ago)
Author:
Rüdiger Stobbe <stobbe@…>
Branches:
(u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
Children:
0af18dde5af4397ff45cd495f0dbf94f4f78bb46
Parents:
7b4bfe63f5e8232ccce6c9f00ab9238ceabc1041
Message:
"New function determinant.
"


git-svn-id: file:///usr/local/Singular/svn/trunk@41 2c84dea3-7e68-4137-9b89-c4e89433aadc
File:
1 edited

Legend:

Unmodified
Added
Removed
  • factory/cf_linsys.cc

    r7b4bfe6 rdb4770  
    11// emacs edit mode for this file is -*- C++ -*-
    2 // $Id: cf_linsys.cc,v 1.0 1996-05-17 10:59:44 stobbe Exp $
     2// $Id: cf_linsys.cc,v 1.1 1996-07-08 08:22:51 stobbe Exp $
    33
    44/*
    55$Log: not supported by cvs2svn $
     6Revision 1.0  1996/05/17 10:59:44  stobbe
     7Initial revision
     8
    69*/
    710
     
    1720
    1821static bool solve ( int **extmat, int nrows, int ncols );
     22int determinant ( int **extmat, int n );
    1923
    2024static CanonicalForm bound ( CanonicalForm ** M, int rows, int cols );
    21 
     25CanonicalForm detbound ( const CFMatrix & M, int rows );
     26
     27bool matrix_in_Z( const CFMatrix & M, int rows )
     28{
     29    int i, j;
     30    for ( i = 1; i <= rows; i++ )
     31        for ( j = 1; j <= rows; j++ )
     32            if ( ! M(i,j).inZ() )
     33                return false;
     34    return true;
     35}
     36
     37bool betterpivot ( const CanonicalForm & oldpivot, const CanonicalForm & newpivot )
     38{
     39    if ( newpivot.isZero() )
     40        return false;
     41    else  if ( oldpivot.isZero() )
     42        return true;
     43    else  if ( level( oldpivot ) > level( newpivot ) )
     44        return true;
     45    else  if ( level( oldpivot ) < level( newpivot ) )
     46        return false;
     47    else
     48        return ( newpivot.lc() < oldpivot.lc() );
     49}
     50
     51bool fuzzy_result;
    2252
    2353void
     
    6292    // Q so far
    6393    Q = p;
    64     while ( Q < B ) {
     94    while ( Q < B && pno < cf_getNumBigPrimes() ) {
    6595        do {
    6696            cout << "trying prime(" << pno << ") = " << flush;
     
    85115        Q = qnew;
    86116    }
     117    if ( pno == cf_getNumBigPrimes() )
     118        fuzzy_result = true;
     119    else
     120        fuzzy_result = false;
    87121    // store the result in M
    88122    Qhalf = Q / 2;
     
    98132    delete [] MM;
    99133    delete [] mm;
     134}
     135
     136CanonicalForm
     137determinant( const CFMatrix & M, int rows )
     138{
     139    ASSERT( rows <= M.rows() && rows <= M.columns() && rows > 0, "undefined determinant" );
     140    if ( rows == 1 )
     141        return M(1,1);
     142    else  if ( rows == 2 )
     143        return M(1,1)*M(2,2)-M(2,1)*M(1,2);
     144    else  if ( matrix_in_Z( M, rows ) ) {
     145        int ** mm = new (int*)[rows];
     146        CanonicalForm Q, Qhalf, mnew, qnew, B;
     147        CanonicalForm det, detnew;
     148        int i, j, p, pno, intdet;
     149        bool ok;
     150
     151        // initialize room to hold the result and the result mod p
     152        for ( i = 0; i < rows; i++ ) {
     153            mm[i] = new int[rows];
     154        }
     155
     156        // calculate the bound for the result
     157        B = detbound( M, rows );
     158
     159        // find a first solution mod p
     160        pno = 0;
     161        do {
     162            p = cf_getBigPrime( pno );
     163            setCharacteristic( p );
     164            ok = true;
     165            // map matrix into char p
     166            for ( i = 0; i < rows && ok; i++ )
     167                for ( j = 0; j < rows && ok; j++ ) {
     168                    if ( M(i+1,j+1).isZero() )
     169                        mm[i][j] = 0;
     170                    else {
     171                        mm[i][j] = mapinto( M(i+1,j+1) ).intval();
     172                        ok = mm[i][j] != 0;
     173                    }
     174                }
     175            pno++;
     176        } while ( ! ok && pno < cf_getNumPrimes() );
     177        // initialize the result matrix with first solution
     178        // solve mod p
     179        intdet = determinant( mm, rows );
     180        setCharacteristic( 0 );
     181        det = intdet;
     182        // Q so far
     183        Q = p;
     184        while ( Q < B && cf_getNumPrimes() > pno ) {
     185            do {
     186                p = cf_getBigPrime( pno );
     187                setCharacteristic( p );
     188                ok = true;
     189                // map matrix into char p
     190                for ( i = 0; i < rows && ok; i++ )
     191                    for ( j = 0; j < rows && ok; j++ ) {
     192                        if ( M(i+1,j+1).isZero() )
     193                            mm[i][j] = 0;
     194                        else {
     195                            mm[i][j] = mapinto( M(i+1,j+1) ).intval();
     196                            ok = mm[i][j] != 0;
     197                        }
     198                    }
     199                pno++;
     200            } while ( ! ok && cf_getNumPrimes() > pno );
     201            // solve mod p
     202            intdet = determinant( mm, rows );
     203            // found a solution mod p
     204            // now chinese remainder it to a solution mod Q*p
     205            setCharacteristic( 0 );
     206            chineseRemainder( det, Q, intdet, p, detnew, qnew );
     207            det = detnew;
     208            Q = qnew;
     209        }
     210        if ( ! ok )
     211            fuzzy_result = true;
     212        else
     213            fuzzy_result = false;
     214        // store the result in M
     215        Qhalf = Q / 2;
     216        if ( det > Qhalf )
     217            det = det - Q;
     218        for ( i = 0; i < rows; i++ )
     219            delete [] mm[i];
     220        delete [] mm;
     221        return det;
     222    }
     223    else {
     224        CFMatrix m( M );
     225        CanonicalForm divisor = 1, pivot, mji;
     226        int i, j, k, sign = 1;
     227        for ( i = 1; i <= rows; i++ ) {
     228            pivot = m(i,i); k = i;
     229            for ( j = i+1; j <= rows; j++ ) {
     230                if ( betterpivot( pivot, m(j,i) ) ) {
     231                    pivot = m(j,i);
     232                    k = j;
     233                }
     234            }
     235            if ( pivot.isZero() )
     236                return 0;
     237            if ( i != k ) {
     238                m.swapRow( i, k );
     239                sign = -sign;
     240            }
     241            for ( j = i+1; j <= rows; j++ ) {
     242                if ( ! m(j,i).isZero() ) {
     243                    divisor *= pivot;
     244                    mji = m(j,i);
     245                    m(j,i) = 0;
     246                    for ( k = i+1; k <= rows; k++ )
     247                        m(j,k) = m(j,k) * pivot - m(i,k)*mji;
     248                }
     249            }
     250        }
     251        pivot = sign;
     252        for ( i = 1; i <= rows; i++ )
     253            pivot *= m(i,i);
     254        return pivot / divisor;
     255    }
    100256}
    101257
     
    116272    }
    117273    sum += vmax;
    118     return sum;
     274    return sqrt( sum );
     275}
     276
     277
     278CanonicalForm
     279detbound ( const CFMatrix & M, int rows )
     280{
     281    CanonicalForm sum = 0, prod = 1;
     282    int i, j;
     283    for ( i = 1; i <= rows; i++ ) {
     284        sum = 0;
     285        for ( j = 1; j <= rows; j++ )
     286            sum += M(i,j) * M(i,j);
     287        prod *= sum;
     288    }
     289    return 2 * sqrt( prod );
    119290}
    120291
     
    168339}
    169340
     341int
     342determinant ( int **extmat, int n )
     343{
     344    int i, j, k;
     345    int divisor, multiplier, rowii, rowji; // all FF
     346    int * rowi; // FF
     347    int * rowj; // FF
     348    int * swap; // FF
     349    // triangularization
     350    multiplier = 1;
     351    divisor = 1;
     352   
     353    for ( i = 0; i < n; i++ ) {
     354        //find "pivot"
     355        for (j = i; j < n; j++ )
     356            if ( extmat[j][i] != 0 ) break;
     357        if ( j == n ) return 0;
     358        if ( j != i ) {
     359            multiplier = ff_neg( multiplier );
     360            swap = extmat[i]; extmat[i] = extmat[j]; extmat[j] = swap;
     361        }
     362        rowi = extmat[i];
     363        rowii = rowi[i];
     364        for ( j = i+1; j < n; j++ ) {
     365            rowj = extmat[j];
     366            rowji = rowj[i];
     367            if ( rowji == 0 ) continue;
     368            divisor = ff_mul( divisor, rowii );
     369            for ( k = i; k < n; k++ )
     370                rowj[k] = ff_sub( ff_mul( rowj[k], rowii ), ff_mul( rowi[k], rowji ) );
     371        }
     372    }
     373    multiplier = ff_mul( multiplier, ff_inv( divisor ) );
     374    for ( i = 0; i < n; i++ )
     375        multiplier = ff_mul( multiplier, extmat[i][i] );
     376    return multiplier;
     377}
     378
    170379void
    171380solveVandermondeT ( const CFArray & a, const CFArray & w, CFArray & x, const Variable & z )
Note: See TracChangeset for help on using the changeset viewer.