Beispiel #1
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()
Beispiel #2
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