Exemple #1
0
            //
            /// <summary>
            /// Ctor() init all.
            /// </summary>
            /// <param name="rettangolareAnalizzanda"></param>
            public CombinationParams(LinearAlgebra.MatrixRank rettangolareAnalizzanda)
            {
                this.leftMostPivoter = rettangolareAnalizzanda.Get_rows - 1;// la minore delle dimensioni.
                //
                this.assignableMaxima = new int[rettangolareAnalizzanda.Get_rows];
                int assignementAccumulator = 0;

                for (int assignableMaximum = rettangolareAnalizzanda.Get_cols - 1; assignementAccumulator < rettangolareAnalizzanda.Get_rows; assignementAccumulator++)
                {
                    assignableMaxima[rettangolareAnalizzanda.Get_rows - assignementAccumulator - 1] = assignableMaximum--;
                }// end for assignableMaxima
                //
                this.indexRange = new int[rettangolareAnalizzanda.Get_cols];// la maggiore delle dimensioni.
                for (int curIndex = 0; curIndex < rettangolareAnalizzanda.Get_cols; curIndex++)
                {
                    this.indexRange[curIndex] = curIndex;
                }// emd for indexRange
                //
                this.naturalIndexes = new int[rettangolareAnalizzanda.Get_rows];
                for (int columnIndex = 0; columnIndex < naturalIndexes.Length; columnIndex++) // per ciascuna colonna
                {
                    naturalIndexes[columnIndex] = columnIndex;                                // set non-pivot columns to their natural index.
                }//NB. all columns are non-pivot, in this phase; one of them will become, later.
                //
                this.thePivotingColumn = rettangolareAnalizzanda.Get_rows - 1;// start from the last on the right.
                //
                this.cardinalitaColonne = rettangolareAnalizzanda.Get_cols;
                this.cardinalitaRighe   = rettangolareAnalizzanda.Get_rows;
                //
            }// end Ctor()
Exemple #2
0
        }// end Rango()

        /// <summary>
        /// gestioneQuadrata
        /// </summary>
        /// <returns></returns>
        private int gestioneQuadrata(LinearAlgebra.MatrixRank quadrataAnalizzanda)
        {
            int    Rango           = 0;   // init
            double curSubMatrixDet = 0.0; // init

            //
            if (quadrataAnalizzanda.Get_rows != quadrataAnalizzanda.Get_cols)
            {
                throw new System.Exception("only square matrices can be accepted by method gestioneQuadrata.");
            }
#if debug
            quadrataAnalizzanda.show();
            System.Console.WriteLine(" dimensione matrice= {0}", quadrataAnalizzanda.Get_rows);
#endif
            //
            if (0 == quadrataAnalizzanda.Get_rows) // size one matrix is a scalar;
            {                                      // zero size matrix is no-number.
                Rango = 0;
                return(Rango);
            }// avoid an exception, due to zero-sized matrix.
            //
            curSubMatrixDet = quadrataAnalizzanda.det();
            if (System.Math.Abs(curSubMatrixDet) > +1.0E-12)    // at the first nonnull minor
            {
                Rango = quadrataAnalizzanda.Get_rows;
                return(Rango);
            }// end if Rango pieno; else continue with recursion.
            //
            involvedDimensions = new System.Collections.ArrayList();// for all dimensions.
            for (int analyzedDimension = quadrataAnalizzanda.Get_rows; analyzedDimension > 0; analyzedDimension--)
            {
                involvedDimensions.Add(new System.Collections.ArrayList()); // add an ArrayList, for each dimension, prior scanning.
            }// end dimensional ArrayList allocation
            Rango = sottomatriciTelescopiche(quadrataAnalizzanda);          //--##########------------solve by recursion-----#########################
            //
            System.Collections.ArrayList finalRankResults = new System.Collections.ArrayList();
            for (int c = 0; c < involvedDimensions.Count; c++)
            {
                // lettoreRisultati( ( ( System.Collections.ArrayList )( involvedDimensions[c] ) ) );  dbg
                if (0 < ((System.Collections.ArrayList)(involvedDimensions[c])).Count)
                {//  if: add only from populated dimensions.
                    SmallerDet curElement = (( SmallerDet )(((System.Collections.ArrayList)(involvedDimensions[c]))[0]));
                    finalRankResults.Add(curElement.SubMatrixSize);
                }// end if: add only from populated dimensions.
            }
            // rilettura risultati finali
            for (int c = 0; c < finalRankResults.Count; c++)
            {
                if ((( int )(finalRankResults[c])) >= Rango)
                {
                    Rango = (( int )(finalRankResults[c]));
                } // else skip smaller Rank.
            }     // end for each finalRankResults
            //
            //ready.
            return(Rango);
        }// end gestioneQuadrata
Exemple #3
0
        }// end ~Dtor().

        #endregion Ctors



        #region Rango



        /// <summary>
        /// dimensione del massimo minore nonnullo. Ovvero numero di linee della piu' grande sottomatrice quadrata, a determinante nonnullo.
        /// La matrice analizzata (i.e. sourceMat) puo' essere rettangolare, con dimensioni qualsiasi. Il massimo rango possibile e' la minore
        /// delle dimensioni della matrice analizzata.
        /// Il caso di matrice in esame rettangolare, costituisce il caso generale. Da esso vengono prodotti molteplici sottocasi di matrice quadrata.
        /// Lo entry point del Rango deve quindi essere una funzione che smista dal caso generale, di input rettangolare, al caso semplificato di input quadrato
        /// Il caso di primo input gia' quadrato, permette soluzione diretta, mediante il medesimo metodo di individuazione delle sottomatrici, utilizzato per i cofattori dell'inversa.
        /// Il caso di primo input rettangolare, richiede invece un'iterazione, per la produzione di tutti i sottocasi quadrati, fino ad individuazione del primo minore nonnullo.
        /// Durante tale processo, sara' utilizzata la variabile "curDimension", ad indicare l'ordine delle sottomatrici quadrate in esame.
        /// Esaurite tutte le sottomatrici quadrate di ordine "curDimension", si passa alla produzione delle quadrate d'ordine "curDimension-1".
        /// Per ogni valore di "curDimension"=="k", si hanno (n k) (i.e. "n" bionomioNewton "k") quadrate kXk, estratte da una rettangolare nXk, con n>k.
        /// Nel caso si parta gia' da una quadrata kXk, si deve in primis calcolarne il determinante. Ove esso sia nullo si opera "--curDimension" e cosi' via.
        /// Le sottofunzioni ad oggi(2015.09.02) individuate sono:
        /// -   selezione di "curDimension": distingue i casi quadrata-rettangolare e imposta "curDimension"
        /// -   "producer" : genera la sottomatrice da analizzare( combinando colonne)
        /// -   "ePermutazioneDi" : valuta se una certa sequenza di indici di colonna sia una permutazione di una gia' valutata; si serve della sottofunzione "appartieneA"
        /// -   "appartieneA" : prende uno scalare, indice di una colonna, e dice se appartiene ad una collezione di indici di colonna, ricevuta a parametro. E' una funzione elementare, con
        ///     schema {1}appartieneA({1,2,3})==true; {7}appartieneA({1,2,3})==false; la precedente funzione "ePermutazioneDi", va implementata considerando il risultato booleano cumulativo
        ///     di "appartieneA", ovvero: {1,3,2}"ePermutazioneDi"({1,2,3})==({1}appartieneA({1,2,3})and{2}appartieneA({1,2,3})and{3}appartieneA({1,2,3}) ).
        /// </summary>
        /// <returns></returns>
        public int Rango() // LinearAlgebra.RealMatrix sourceMat )
        {                  // schema operativo:
            //NB. il numero antistante la riga, indica la funzione nella quale viene svolto il task.
            // legenda:
            // (1)==EntryPoint()( i. e. rango).
            // (2)==gestioneQuadrata().
            // (3)==gestioneRettangolare().
            // (4)==producer().
            // (5)==selettore().
            // (6)==ePermutazioneDi().
            // (7)==appartieneA().
            //------------------------------------------------------------------------
            // 1) distinguere tra sourceMat quadrata e sourceMat rettangolare
            // 1) individuare la minore fra le cardinalita', di riga e di colonna e valorizzare la variabile "curDimension"
            // 2) incaso di sourceMat quadrata, ->gestioneQuadrata() e uscita.
            // 3) incaso di sourceMat rettangolare, ->gestioneRettangolare(), da cui (4)producer->(5)selettore->(6)ePermutazioneDi->appartieneA()->gestioneQuadrata()->rientro a
            //    gestioneRettangolare() per l'estrazione delle quadrate successive.
            // (4)Osservazioni sul producer(4):comporre le sottomatrici, formando le combinazioni semplici( i.e. senza ripetizione) delle "n" linee, prese "k" per volta.
            // (4)tali combinazioni semplici hanno cardinalita' (n k), nel senso del binomio di Newton; ovvero "k" elenti, estratti da un insieme di cardinalita' "n", senza possibilita'
            // (4)di reinserimento del medesimo elemento e con irrilevanza dell'ordine. Oss. k<=n.
            //
            int  curDimension;
            bool isSquare = false;
            int  Rango;

            LinearAlgebra.MatrixRank workCopy = null;
            //
            if (this.Get_cols < this.Get_rows)
            {
                workCopy     = new MatrixRank(this.transpose());
                curDimension = this.Get_cols;//---###################### the minimum between the two dimensions, becomes curDimension ##############
            }// end if ( this.Get_cols < this.Get_rows )
            else if (this.Get_cols > this.Get_rows)
            {                                        // i.e. Get_cols > Get_rows
                workCopy     = new MatrixRank(this); // keep it as is.
                curDimension = this.Get_rows;        //---###################### the minimum between the two dimensions, becomes curDimension ##############
            }// end if Get_cols >= Get_rows
            else //   this.Get_cols == this.Get_rows
            {
                workCopy     = new MatrixRank(this); // keep it as is.
                curDimension = this.Get_rows;        //---###################### the minimum between the two dimensions, becomes curDimension ##############
                isSquare     = true;
            }// end if.
            //
            if (isSquare)
            {
                Rango = this.gestioneQuadrata(workCopy);  //----------###################### NonTailrecursion ##########################################################
            }
            else
            {
                Rango = this.gestioneRettangolare(workCopy);  //--------############# Produzione sottomatrici quadrate ed iterazione su this.gestioneQuadrata() ########
            }
            //ready.
            return(Rango);
        }// end Rango()
Exemple #4
0
        }// end sottomatriciTelescopiche()

        /// <summary>
        /// Tiene costanti tutti gli indici di colonna, tranne uno. Su questo itera, attribuendo tutti gli indici del range(i.e. la dimensione massima fra le due; a valle della
        /// trasposizione e' l'indice delle colonne>righe).
        /// Cosi' facendo produce configurazioni, che vanno date in esame a "selettore", per verificare che siano effettivamente nuove.
        /// Data una rettangolare nXk (con n>k; in caso sia kxn si traspone, senza effetti sui minori), ci sono n_binomio_k combinazioni semplici( i.e. senza ripetizione)
        /// delle "n" colonne, prese "k" a "k".
        /// il producer implementa i cicli necessari a combinare gli indici di colonna; ad ogni combinazione prodotta, entra in azione il selettore, per stabilire se tale
        /// configurazione sia da utilizzare( ovvero calcolarne il determinante) o da scartare.
        /// Solo nel caso il selettore risponda di utilizzare la configuazione, essa viene restituita sotto forma di LinearAlgebra.RealMatrix; altrimenti si fa "continue" nei
        /// cicli di produzione. Osservazione: quando viene prodotta una sottomatrice quadrata, essa viene lavorata sino al piu' piccolo dei suoi minori e qundi viene associato
        /// il rango di tale sottomatrice, al vettore di indici della sua configurazione. Sarebbe problematico esplorare solo la "curDimension" e poi dover tornare sulla medesima
        /// configurazione, quando fosse intervenuto un "--curDimension".
        /// </summary>
        private int gestioneRettangolare(LinearAlgebra.MatrixRank rettangolareAnalizzanda)
        {                                                                            // since columns are more than Get_rows( always after translation), the simple combinations are cardinality of sorceMat.Get_cols taken
            // rettangolareAnalizzanda.Get_rows each time ( i.e. sorceMat.Get_cols Newton binomial rettangolareAnalizzanda.Get_rows ).
            this.combinationParams = new CombinationParams(rettangolareAnalizzanda); //  nullify on exit, for gc.
            int binomioN = binomioNewton(rettangolareAnalizzanda.Get_cols, rettangolareAnalizzanda.Get_rows);

            this.RankSequence = new SquareSmallerRank[binomioN];
            //
            // ciclo di lavorazione del vettore di configurazioni.
            for (int SquareSmallerRank_element = 0; SquareSmallerRank_element < this.RankSequence.Length; SquareSmallerRank_element++) // ciclo di lavorazione del vettore di configurazioni.
            {                                                                                                                          // allocazione del singolo record di configurazione: chiama il Ctor() della struttura e imposta il vettore degli indici, al numero effettivo delle colonne.
                this.RankSequence[SquareSmallerRank_element] = new SquareSmallerRank(rettangolareAnalizzanda.Get_rows);
                //
                if (SquareSmallerRank_element == 0)
                {
                    this.RankSequence[SquareSmallerRank_element].columnIndexes = this.combinationParams.naturalIndexes;
                }
                else if (SquareSmallerRank_element > 0)
                {
                    for (int c = 0; c < rettangolareAnalizzanda.Get_rows; c++)
                    {                                                                                                                                      // NB. e' cruciale assegnare per singolo scalare, in modo da copiare by_value; se si assegna il vettore in un colpo, viene assegnato il puntatore
                        // e i vettori delle diverse strutture puntano alla stessa copia in memoria.
                        this.RankSequence[SquareSmallerRank_element].columnIndexes[c] = this.RankSequence[SquareSmallerRank_element - 1].columnIndexes[c]; // as the preceeding one.
                    }
                    producer(this.RankSequence[SquareSmallerRank_element].columnIndexes);
                }
                //bool bocciato = this.selettore( this.RankSequence[SquareSmallerRank_element].columnIndexes ); ex codice TODO eliminare
                //if ( bocciato )
                //{
                //    throw new System.Exception("configurazione bocciata dal selettore.");
                //}
                //
#if debug
                //-----debug output
                for (int columnIndex = 0; columnIndex < rettangolareAnalizzanda.Get_rows; columnIndex++)// per ciascuna colonna, compresa l'ultima
                {
                    System.Console.WriteLine(" record # {0} ", this.RankSequence[SquareSmallerRank_element].columnIndexes[columnIndex]);
                }// end output del vettore di indici di colonna, per debug.
                System.Console.WriteLine(" fine record nr.{0}\n\n ", SquareSmallerRank_element);
#endif
                //
            }// end for RankSequence
            //
            //----ciclo valorizzazione del campo "Rank" nel vettore RankSequence
            for (int SquareSmallerRank_element = 0; SquareSmallerRank_element < this.RankSequence.Length; SquareSmallerRank_element++) // ciclo di lavorazione del vettore di configurazioni.
            {                                                                                                                          //----ciclo valorizzazione del campo "Rank" nel vettore RankSequence
                LinearAlgebra.MatrixRank rankBanco = new MatrixRank(this.combinationParams.cardinalitaRighe, this.combinationParams.cardinalitaRighe);
                for (int c = 0; c < this.combinationParams.cardinalitaRighe; c++)
                {
                    bool colInserted = rankBanco.putCol(c, rettangolareAnalizzanda.getCol(this.RankSequence[SquareSmallerRank_element].columnIndexes[c]));
#if debug
                    System.Console.WriteLine(" record # {0} ", this.RankSequence[SquareSmallerRank_element].columnIndexes[c]);
#endif
                }// end construction by columns
#if debug
                System.Console.WriteLine(" fine record nr.{0}\n\n ", SquareSmallerRank_element);
#endif
                // now compute the rank on such SubMatrix
                this.RankSequence[SquareSmallerRank_element].Rank = gestioneQuadrata(rankBanco);
                rankBanco.deallocator_publicProxy(); // gc, to avoid any risk of using old data.
                rankBanco = null;                    // gc, to avoid any risk of using old data.
            }// end --ciclo valorizzazione del campo "Rank" nel vettore RankSequence
            //
            //----ciclo di determinazione del massimo, fra i ranghi, nel vettore RankSequence
            int MaxDeiRanghi         = 0;                                                                                              // init and then compare with actual values.
            int MaxRankConfiguration = 0;
            for (int SquareSmallerRank_element = 0; SquareSmallerRank_element < this.RankSequence.Length; SquareSmallerRank_element++) // ciclo di lavorazione del vettore di configurazioni.
            {                                                                                                                          //----ciclo di determinazione del massimo, fra i ranghi, nel vettore RankSequence
                if (MaxDeiRanghi < this.RankSequence[SquareSmallerRank_element].Rank)
                {
                    MaxDeiRanghi         = this.RankSequence[SquareSmallerRank_element].Rank;
                    MaxRankConfiguration = SquareSmallerRank_element;// memorize which configuration ha s the maximum rank.
                }// end rank comparison, on the single scalar.
            }// end ---ciclo di determinazione del massimo, fra i ranghi( array), nel vettore RankSequence
            //
            this.combinationParams = null;// garbage collect.
            return(MaxDeiRanghi);
        }// end gestioneRettangolare