Torna indietro   Hardware Upgrade Forum > Software > Programmazione

KTC H27E6 a 300Hz e 1ms: come i rivali ma a metà prezzo
KTC H27E6 a 300Hz e 1ms: come i rivali ma a metà prezzo
KTC lancia il nuovo monitor gaming H27E6, un modello da 27 pollici che promette prestazioni estreme grazie al pannello Fast IPS con risoluzione 2K QHD (2560x1440). Il monitor si posiziona come una scelta cruciale per gli appassionati di eSport e i professionisti creativi, combinando una frequenza di aggiornamento di 300Hz e un tempo di risposta di 1ms con un'eccezionale fedeltà cromatica
Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare
Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare
Realizzato da Lenovo e installato presso il Cineca di Casalecchio di Reno, Pitagora offre circa 44 PFlop/s di potenza di calcolo ed è dedicato alla simulazione della fisica del plasma e allo studio dei materiali avanzati per la fusione, integrandosi nell’ecosistema del Tecnopolo di Bologna come infrastruttura strategica finanziata da EUROfusion e gestita in collaborazione con ENEA
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA
Rullo di lavaggio dei pavimenti abbinato a un potente motore da 28.000 Pa e a bracci esterni che si estendono: queste, e molte altre, le caratteristiche tecniche di Z60 Ultra Roller Complete, l'ultimo robot di Mova che pulisce secondo le nostre preferenze oppure lasciando far tutto alla ricca logica di intelligenza artificiale integrata
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 16-07-2008, 21:53   #1
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
[LINQ] analisi di matrici

Finora con linq ho lavorato prettamente con dati sequenziali, ma come dovrebbe funzionare in caso di matrici n-dimensionali?
E' possibile utilizzarlo efficacemente o è limitato solo a collection uni-dimensionali?
Ho fatto una rapida prova con una matrice di interi con questo codice:
Codice:
int[][] matrix = {
                             new int[]{1,2,3},
                             new int[]{4,5,6},
                             new int[]{7,8,9}};

            var result = matrix.Select(row => row.Where(value => value > 5));
            foreach (var r in result) r.ForEach(Console.WriteLine);
Che da il risultato voluto, ovvero restituisce i numeri 6, 7, 8 e 9, però ho dovuto usare una Select sulla matrice.
Così facendo in pratica ho ricevuto 3 oggetti Enumerable, mentre ad esempio del primo non saprei che farmene dato che non contiene nessun oggetto maggiore di 5.
Avevo provato inizialmente ad usare un altro Where al posto del Select ma non buildava...
Quale sarebbe quindi la soluzione migliore (se esiste) per lavorare su dati di tipo matriciale con Linq?
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 08:13   #2
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
A naso sembra che lavori sempre con dati sequenziali, come anche il tuo esempio dimostra.

Non mi sembra un limite. Tra l'altro finora non m'è mai capitato di lavorare con matrici (omogenee) multidimensionali.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 09:33   #3
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Si', lavora su elementi monodimensionali, ma a tutto c'e' una soluzione.
Ti passo qui 3 modi di risolvere il problema, con l'extension a corredo
Il primo e' piu' simile al tuo, ma con la SelectMany eviti di dover usare un terzo enumeratore.
In pratica la SelectMany e' la UNION ALL dell'SQL, che unisce insieme gli elementi di una sottoenumerazione.

Il secondo fa uso di una Matrice Multidimensionale, con a corredo un AsEnumerable per poter ciclare sugli elementi.
Dovrebbe essere la soluzione migliore per le matrici in C#, dato che rango della matrice e lunghezza di ciascuna dimensione sono fissi e il compilatore lo sa a compile-time.

Il terzo e' di nuovo simile al primo, ma usa una doppia enumerazione creata al volo per accedere ai singoli elementi.
Ovviamente non funziona se la matrice e' atipica (con lunghezza di righe diversa)
In pratica mette in prodotto cartesiano le due enumerazioni, costruendo quindi ogni coppia possibile di X e Y.
Sembra essere la soluzione preferita in caso di computo di grosse moli di lavoro per ciascun elemento, dato che puo' essere resa parallelizzabile semplicemente se al posto della prima Enumerable usi una ParallelEnumerable. Ma non ho fatto studi di fattibilita' in tal senso sugli altri esempi.

Codice:
static class Program
{
    static void Main(string[] args)
    {
        int[][] matrix = {
                         new int[]{1,2,3},
                         new int[]{4,5,6},
                         new int[]{7,8,9}};

        var result = matrix.SelectMany(row => row.Where(value => value > 5));

        result.ForEach(Console.WriteLine);

        Console.ReadKey();
    }


    static void Main2(string[] args)
    {
        int[,] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

        var result = matrix.AsEnumerable().Where(t => t > 5);
        result.ForEach(Console.WriteLine);

        Console.ReadKey();
    }

    static void Main3(string[] args)
    {
        int[][] matrix = {
                         new int[]{1,2,3},
                         new int[]{4,5,6},
                         new int[]{7,8,9}};

        int rank = matrix.Rank;
        int dim1 = matrix.Length;
        int dim2 = matrix[0].Length;

        var result = from y in Enumerable.Range(0, dim1)
                     from x in Enumerable.Range(0, dim2)
                     let val= matrix[y][x]
                     where val>5
                     select val;


        result.ForEach(Console.WriteLine);

        Console.ReadKey();
    }

    static IEnumerable<T> AsEnumerable<T>(this T[,] domain)
    {
        foreach (T elem in domain)
            yield return elem;
    }

    static void ForEach<T>(this IEnumerable<T> domain, Action<T> action)
    {
        foreach (T t in domain) action(t);
    }
}
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 10:41   #4
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Piu' interessante potrebbe essere costruire un metodo tipo:

Data una matrice bidimensionale, restituire una matrice bidimensionale di pari geometria, ma con valorizzate solo le celle che soddisfano un determinato filtro.

Es: elemento>5

Con anche il filtro passato come parametro, diverso di volta in volta.
Ho provato, possono venire fuori cose interessanti.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 14:24   #5
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
Il metodo + interessante mi sembra così ad occhio il secondo.
Nel terzo metodo ho scoperto le doppie enumerazioni che ancora non avevo mai visto
ora vedo se riesco a restituire la matrice originale con valorizzati i parametri che soddisfano la condizione espressa nel filtro
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 15:02   #6
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
l'implementazione + semplice che mi è venuta in mente è questa:
Codice:
class Program
    {
        static void Main(string[] args)
        {
            int[][] matrix = {
                             new int[]{1,2,3},
                             new int[]{4,5,6},
                             new int[]{7,8,9}};

            var result = matrix.Select(row => row.Select(value => value > 5 ? value : 0));
            
            foreach (var row in result) 
            {
                foreach (var value in row)
                {
                    Console.Write(value);
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
ce ne sono di migliori che mi sono sfuggite?
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 15:05   #7
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Il requisito che avevo in mente era una funzione che, dato in ingresso una matrice tipo int [][]
restituisse di nuovo un oggetto matrice, con la stessa geometria, applicando il filtro agli elementi.

Intendo una matrice vera, non solo a video
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 15:13   #8
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
Il requisito che avevo in mente era una funzione che, dato in ingresso una matrice tipo int [][]
restituisse di nuovo un oggetto matrice, con la stessa geometria, applicando il filtro agli elementi.

Intendo una matrice vera, non solo a video
ah ok
ora non ho tempo che ho chiuso parallels e devo scappare al lavoro
gli do un occhiatina stasera
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2008, 00:16   #9
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
non riesco a fare andare il predicate
Codice:
class Program
    {

        static void Main(string[] args)
        {
            int[][] matrix = {
                             new int[]{1,2,3},
                             new int[]{4,5,6},
                             new int[]{7,8,9}};

            int[][] result = matrix.Filter(value => value > 5);   
            
            foreach (int[] row in result) {
                foreach (int value in row)
                {
                    Console.Write(value);
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
    }
mi da errore nella riga in bold dicendo:
"Error 1 The type arguments for method 'ProvaLinq.Extensions.Filter<TSource>(int[][], System.Func<int,bool>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. C:\Visual Studio 2008\Projects\ProvaLinq\ProvaLinq\Program.cs 18 30 ProvaLinq"
l'extension method è il seguente:
Codice:
public static int[][] Filter<TSource>(this int[][] matrix, Func<int, bool> predicate)
        {
            return matrix.Select(row => row.Select(value => predicate(value) ? value : 0).ToArray<int>()).ToArray<int[]>();
        }
Ovviamente senza predicate riesco a farla funzionare, ma ancora come utilizzare i delegates durante l'implementazione devo capirlo...
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2008, 10:58   #10
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
ce l'ho fatta..
a mente libera ho risolto il problema
Codice:
public static int[][] Filter(this int[][] matrix, Func<int, bool> predicate)
        {
            return matrix.Select(row => row.Select(value => predicate(value) ? value : 0).ToArray<int>()).ToArray<int[]>();
        }
certo che però ancora non ho capito proprio tutto di queste funzioni implementate in questo modo...
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2008, 11:38   #11
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Giusto, provo a postare le mie 2 versioni di Generics Extension, che si possono applicare a tutte le matrici bidimensionali.
La sostanza principale era quella di dotare la funzione di un funzionale di filtro (il tuo Func<int,bool>) da poter applciare dinamicamente, e che puo' essere risolto dall'utilizzatore mediante una comodissima lambda function.

Per matrice bidimensionale ho inteso proprio la matrice C# con la sintassi [y,x] e non quella tipica del C e C++ come la [y][x]
Ovvio che si possono portare anche per la versione piu' vecchia.

La prima versione e' iterativa, la seconda e' funzionale.
Per questo caso penso che avrei scelto la iterativa.
Codice:
public static T[,] GetFiltered<T>(this T[,] domain, Func<T, bool> pass)
{            
    int dy = domain.GetLength(0); //0 e 1 sono le dimensioni.
    int dx = domain.GetLength(1);
    T[,] ret = new T[dy, dx];

    for (int y = 0; y < dy; y++)
    {
        for (int x = 0; x < dx; x++)
        {
            T test = domain[y,x];
            ret[y, x] = pass(test) ? test : default(T);
        }
    }
    return ret;
}

public static T[,] GetFiltered2<T>(this T[,] domain, Func<T, bool> pass)
{
    int dy = domain.GetLength(0);
    int dx = domain.GetLength(1);
    T[,] ret = new T[dy, dx];

    var universe = from y in Enumerable.Range(0, dy)
                   from x in Enumerable.Range(0, dx)
                   let test = domain[y, x]
                   let res = pass(test) ? test : default(T)
                   select new {y=y,x=x,res=res};

    universe.ForEach(an => ret[an.y, an.x] = an.res);
    
    return ret;
}

public static void ForEach<T>(this IEnumerable<T> domain, Action<T> action)
{
    foreach (T t in domain) action(t);
}
E l'uso che se ne puo' fare e' p.es.:
Codice:
static void Main(string[] args)
{
    int[,] Mat1 = { { 1, 2, 3 }, { 4, 5, 6 } };
    int[,] Mat1Filt = Mat1.GetFiltered(t => t > 4);

    double[,] Mat2 = { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 } };
    double[,] Mat2Filt = Mat2.GetFiltered2(u => u > 4.5);
}
Tutto fortemente tipizzato e lamentato a compile time se qualche tipo esce fuori dai ranghi.

Ora, sto cercando di capire se e' possibile avere davvero un enumeratore doppio. Intendo, un'enumerazione che abbia alla fine non un sola dimensione ma piu' di una.

L'enumerazione di cui sopra restituisce una serie di oggetti. Ogni oggetto contiene le 2 coordinate (e il risultato del filtro), e su questo ho giocato.
Mi sarebbe invece piaciuto ottenere un'enumerazione doppia, con 2 parametri interi (u,v) invece che uno solo tipizzato (t)

E' una questione di lana caprina, ma mi sarebbe piacuto scrivere qualcosa come la prima, invece che la seconda.
Codice:
universe.ForEach((t, u) => ret[t, u] = qualcosa);

universe.ForEach(an => ret[an.y, an.x] = qualocosa);
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.

Ultima modifica di gugoXX : 18-07-2008 alle 11:46.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


KTC H27E6 a 300Hz e 1ms: come i rivali ma a metà prezzo KTC H27E6 a 300Hz e 1ms: come i rivali ma a met&...
Cineca inaugura Pitagora, il supercomputer Lenovo per la ricerca sulla fusione nucleare Cineca inaugura Pitagora, il supercomputer Lenov...
Mova Z60 Ultra Roller Complete: pulisce bene grazie anche all'IA Mova Z60 Ultra Roller Complete: pulisce bene gra...
Renault Twingo E-Tech Electric: che prezzo! Renault Twingo E-Tech Electric: che prezzo!
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media Il cuore digitale di F1 a Biggin Hill: l'infrast...
GeForce RTX 50 SUPER cancellate o rimand...
Windows 11 si prepara a vibrare: Microso...
La “Burnout Season” colpisce l’Italia: i...
QNAP annuncia il JBOD TL-R6020Sep-RP: ol...
Siemens e NVIDIA uniscono le forze: arri...
Ricarica veloce e durata batteria: miti ...
Le "navi volanti" di Candela a...
Bambini su misura? Il caso della startup...
Iliad porta le SIM Express in edicola: r...
Offerte Amazon sui TV Mini LED Hisense 2...
Il silenzio digitale che fa male: come i...
Il responsabile del programma Cybertruck...
Domanda alle stelle per SSD e RAM: in Gi...
Zuckerberg vuole eliminare tutte le mala...
Otto suicidi, un solo chatbot: si moltip...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 19:04.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v