Pagina 1 di 2

[Mathematica]

MessaggioInviato: 16/04/2019, 08:53
da davidefilotto
Salve a tutti, sono alle prime armi con il programma Mathematica e ho riscontrato alcune difficoltà.
Premetto che non sono ferrato nella programmazione :)
In un esercizio senza valutazione finale mi si chiede di generare una matrice di numeri random, con numero di righe minore di 20, e ogni riga di numero di colonne random, ma minore di 10.
Devo poi definire una distanza tra due numeri che ritorni True, se i due numeri differiscono al più del 10% della loro media, e False altrimenti. Implementare la funzione in modo che la soglia sia un parametro opzionale della funzione.
A partire dall'ultimo elemento dell'ultima riga, raggruppare gli elementi in base alla distanza precedentemente definita. Nell'eseguire questo raggruppamento scartate gli elementi già inseriti in precedenza in un altro gruppo. Inoltre tenere traccia di quali posizioni della matrice appartengono a quale gruppo.

Adesso, io ho (credo) fatto la matrice random in questo modo:

GenerateData[maxCols_, maxRows_] :=
Table[
RandomReal[], {RandomInteger[{1, maxRows}]}, {RandomInteger[{1,
maxCols}]}]
RndMatrix = GenerateData[20, 10]
TableForm[RndMatrix]


Da qui come posso andare avanti?
Grazie

Re: [Mathematica]

MessaggioInviato: 16/04/2019, 09:40
da davidefilotto
Ho provato ad aggiungere questa parte:

Funzione[a_, b_] := Module[{differenza, media},
differenza = a - b;
media = (a - b)/2;
]
If[TrueQ[media < 0.1], media, 0]

Re: [Mathematica]

MessaggioInviato: 17/04/2019, 06:35
da davidefilotto
Nessuno?

Re: [Mathematica]

MessaggioInviato: 17/04/2019, 11:05
da fmnq
"differire al più del 10% della loro media" significa che $|a-b| < \frac{a+b}{20}$; puoi perciò semplicemente definire
Codice:
AreNear[a_,b_][threshold_: 0.1] := Abs[a-b] < threshold * (a+b)/2
(o qualcosa di molto simile che tiene conto del segno di $a,b$).

Re: [Mathematica]

MessaggioInviato: 17/04/2019, 11:52
da davidefilotto
Grazie, ho capito! Adesso dovrei fare un ciclo If per avere i raggruppamenti. Come si può fare per raggruppare gli elementi in base a questa distanza definita, partendo dall'ultimo elemento dell'ultima riga?

Re: [Mathematica]

MessaggioInviato: 17/04/2019, 12:05
da fmnq
Che cosa significa che li devi "raggruppare"? L'ordine in cui appaiono è importante o devi solo dividerli in quelli che soddisfano il predicato e quelli che non lo soddisfano?

Devi dare come input la matrice, e come risultato una lista di liste che contiene tutti gli elementi consecutivi che sono "Near", oppure mettere in una sottolista quelli che lo sono e quelli che no? Nel primo caso, si tratta di usare un groupBy sull'appiattimento della matrice rovesciata: una cosa tipo
Codice:
λM.GroupBy[M//Flatten//Reverse, AreNear]

e nel secondo caso, invece, devi usare la funzione GatherBy invece di GroupBy.

Re: [Mathematica]

MessaggioInviato: 17/04/2019, 13:26
da davidefilotto
Devo raggruppare gli elementi in base alla distanza definita prima. Nell'eseguire questo raggruppamento devo scattare gli elementi già inseriti in precedenza in un altro gruppo. Inoltre tenere traccia di quali posizioni della matrice appartengono a quale gruppo.

Re: [Mathematica]

MessaggioInviato: 17/04/2019, 20:11
da davidefilotto
@fmnq non riesco a scriverti in pvt

Re: [Mathematica]

MessaggioInviato: 17/04/2019, 20:15
da fmnq
Ancora non è chiaro cosa devi fare. mettiamo che nella lista $[a_1, ..., a_6]$ i primi due elementi e il quinto e sesto siano "Near": quello che vuoi come output è la lista \([[a_1,a_2], [a_3, a_4], [a_5, a_6]]\) oppure la lista $[[a_1,a_2,a_5,a_6], etc]$?

Re: [Mathematica]

MessaggioInviato: 17/04/2019, 20:29
da davidefilotto
La seconda opzione. Devo fare prima un sottogruppo con tutti i numeri che rientrano nella definizione, e togliere questi numeri dal gruppo iniziale. Poi devo ripetere l'operazione sul gruppo iniziale al quale ho già sottratto il sottogruppo, e così via.