interpolazione tabella 2D

Ciao Ragazzi,

Sto sviluppando un progetto che dovrebbe darmi in uscita una variabile calcolata in base a due letture prese da un pin analogico e da un calcolo di un interrupt.

Sono riuscito già a calcolarmi tutto quindi ho le due variabili di ingresso pronte. Il mio problema è che la variabile in uscita non è direttamente dipendende dalle due in ingresso esempio (A+36 x B + 36 ) ma bensì dovrei andare a leggere una tabella 2d dopve le variabili in ingresso rappresentano i due assi e la variabile in uscita è il valore di incrocio.

Oltre a questo, ovviamente, dovrei interpolare.
Ho provato ad ottenere questo facendo un test su una porziopne limitata di tabella utilizzando tanti "if" e specificando ogni volta le condizioni di interpolazione.

Questo oltre ad essere molto lungo da scrivere credo sia anche molto macchinoso per il processore oltre che avere un ultimo svantaggio: se volessi cambiare i tati della tabella dovrei in pratica riscrivere tutto il codice.

Esiste una funzione più semplice in cui poter inserire i dati che "legga" le variabili di ingresso e mi restituisca l'uscita "leggendo" la look-up table e interpolando ?

Ho letto della funzione multimap ma non mi è molto chiara.

Ho pensato anche di approssimare le varie curve con delle funzioni polinomiali di grado "n" così da utilizzare solo un numero limitato di if poi far svolgere al processore l'operazione ma non sembra essere molto semplice.

grazie in anticipo per l'aiuto

Michele

Ciao! Non so interpolare dati, ma non si può scorrere la tabella che immagino sia una matrice, e negli if con le condizioni farli lavorare su dati diversi.

Non so interpolare, ma nei vari if() cambiano le condizioni o cambiano i dati, perché se fosse che cambiano i dati sicuramente si può risolvere con cicli e particolari condizioni di ciclo.

Mmmm ... io cercherei di applicare un'interpolazione e poi cercherei di scrivere una funzione che la esegue ...
... QUI ed anche QUI un po' di teoria ed un po' di formule :wink:

Guglielmo

Questa la so finalmente

Basta usare la regressione di excel

miche91:
Sono riuscito già a calcolarmi tutto quindi ho le due variabili di ingresso pronte. Il mio problema è che la variabile in uscita non è direttamente dipendende dalle due in ingresso esempio (A+36 x B + 36 ) ma bensì dovrei andare a leggere una tabella 2d dopve le variabili in ingresso rappresentano i due assi e la variabile in uscita è il valore di incrocio.

Forse non ho capito. Le variabili di ingresso per la tabella di look-up, sono gli indici della matrice o no?

Federico

AmericanDreamer:
Questa la so finalmente

Basta usare la regressione di excel

Cosa intendi ?

Federico66:
Forse non ho capito. Le variabili di ingresso per la tabella di look-up, sono gli indici della matrice o no?

Federico

Si una variabile é il numero della riga e una variabile é il numero della colonna ma poi devo interpolare i valori intermedi

gpb01:
Mmmm ... io cercherei di applicare un'interpolazione e poi cercherei di scrivere una funzione che la esegue ...
... QUI ed anche QUI un po' di teoria ed un po' di formule :wink:

Guglielmo

Grazie , mi metto subito a guardare

Grazie a tutti

miche91:
Cosa intendi ?

Apri excel e cerchi lo help di regressione

AmericanDreamer:
Apri excel e cerchi lo help di regressione

Ok ma non capisco cosa c'entra con arduino. Io devo implementarlo su arduino non devo farlo con excel

1 Like

La regressione ti da la funzione

Stasera sono poeta

Poi in Arduino la importi

Scusa, rileggendo mi sono accorto d'aver fatto una domanda stupida :frowning:

Premessa:
la statistica non è proprio il mio forte, ma mi piacciono le sfide, quindi ho studiato un po' e ci provo, ma ti prego di cercare conferme, e non prendere quello che dico per oro colato!

Per chiarezza faccio un esempio:

  • la tabella (arr[6][6]) di look-up e del tipo
|___|___|___|___|___|_c_|___|
|___|  0| 10| 20| 30| 40| 50|
|___|100|110|120|130|140|150|
|_r_|200|210|220|230|240|250|
|___|300|310|320|330|340|350|
|___|400|410|420|430|440|450|
|___|500|510|520|530|540|550|

dove nella prima colonna e nella prima riga ci sono i valori di lettura, e ad ogni incrocio c'è il valore cercato X

  • in ingresso hai due valori (R,C)
  • se i valori in ingresso sono valori presenti, (100,30), allora il valore cercato X=130
  • se i valori in ingresso sono valori intermedi, (110,35), allora devi estrarre le quattro coppie di valori che idealmente circondano il valore cercato, e interpolarli per ottenerlo.

Per estrarre le quattro coppie valori, la vedo abbastanza semplice ed è indipendente dai dati della matrice:

  • cicli sulle righe fino a trovare il primo valore >= R (200), con indice r
  • ti fermi e cicli sulle colonne della riga r fino a trovare il primo valore >= C (240), con indice c
  • a questo punto le quattro coppie di valori cercati per la coppia (110,35) sono
arr[r-1][c-1] => (100,30) = 130
arr[r-1][c] => (100,40) = 140
arr[r][c-1] => (200,30) = 230
arr[r][c] => (200,40) = 240

a questo punto devi decidere che tipo di interpolazione vuoi usare, sulla base della precisione che vuoi ottenere, e quindi implementare la/le formule più adatte.
Per l'interpolazione lineare, la cosa (forse) è abbastanza semplice da fare, per le altre la vedo più complicata e forse ti conviene cercare implementazioni già fatte!

Per la lineare dovrebbe essere:

R1=100, C1=30 => X1 = 130
R1=100, C2=40 => X2 = 140
R2=200, C1=30 => X3 = 230
R2=200, C2=40 => X4 = 240
R=110, C=35 => X

X = (((R2-R)/(R2-R1))*X1 + ((R-R1)/(R2-R1))X2)(C2-C)/(C2-C1)
+
(((R2-R)/(R2-R1))*X3 + ((R-R1)/(R2-R1))X4)(C-C1)/(C2-C1)

X = (((C2-C)/(C2-C1))*X1+(C-C1)/(C2-C1)X2)((R2-R)/(R2-R1))
+
(((C2-C)/(C2-C1))*X3+(C-C1)/(C2-C1)X4)((R-R1)/(R2-R1))

Non ho testato, quindi ti prego di verificare la formula!!!
(o meglio, l'ho provata in excel, ed il risultato mi sembra plausibile)

Naturalmente ci sono i casi particolari, quando R o C coincidono con il valore cercato nella tabella, quindi stai attento alle divisioni per zero, probabilmente ti conviene utilizzare una formula semplificata!!

Se il tutto è corretto, dovresti creare una funzione che:

  • accetta come parametri R e C
  • cerca i valori nella matrice di look-up
  • applica l'interpolazione ai valori trovati
  • ritorna il valore cercato X

Spero di non aver fatto più danni che bene :confused:
Federico

PS
Naturalmente spero ci sia qualcuno più ferrato in statistica che possa aiutarti

Cosa che vale solo per fenomeni strettamente lineari

Ma che comunque ha errore piccolo, minore del la distanza vita due campioni

Grazie a tutti. Allora partiamo da quello che dice AmericanDreamer. ho provato a fare quanto suggerito e in realta sembra essere interessante. ovviamente devo adottare una regressione polinomiale , con un polinomio di 5 o 6 ordine riesco a ottenere una ottima approssimazione.

I problemi che sorgono adesso sono principalmente 2:

1- mi creo delle curve che descrivono tutti gli infiniti valori di X ma solo n valori di Y (o viceversa) quindi poi per valori intermedi devo comunuqe interpolare 2 risultati di due curve vicine al valore intermedio stesso (che non è un grosso problema)

2- devo capire come verificare se un polinomio del 6 ordine è gestibile in tempi accettabili dal microprocessore di arduino

In linea generale mi sembra un ottima soluzione, devo finire di affinare la formula che mi restituisce excel perchè mi escono delle formule un po' strane tipo

y = 8E-20x6 - 1E-15x5 + 7E-12x4 - 2E-08x3 + 3E-05x2 - 0.0276x + 10

Federico non ho pensato alla tua soluzione ma sembra molto molto interessante. L'interpolazione lineare non sarebbe il massimo ma forse considerando magari 8 o 12 campioni circostanti invece che 4 potremmo migliroare l'accuratezza.

Questa soluzione per me è un po' poù difficile da inserire nel codice. Appena riesco continuo a fare prove.
Come implementeresti i cicli?

grazie

miche91:
mi creo delle curve che descrivono tutti gli infiniti valori di X ma solo n valori di Y (o viceversa) quindi poi per valori intermedi devo comunque interpolare

Ma la tabella di quanti elementi X Y è composta? E la rappresentazione Z in 3D è molto "frastagliata" piena di picchi e valli, oppure abbastanza "collinosa" e uniforme?

Non per interrompere lo sviluppo già in corso, ma come idea alternativa l'interpolazione di una funzione N dimensionale non lineare può essere il compito perfetto per una rete neurale. Ad esempio con solo sette unità si è già in grado di calcolare contemporaneamente angolo e velocità di lancio di un oggetto partendo dalla distanza da raggiungere e dal tempo.

Si tratterebbe quindi di vedere com'è la 3D del caso specifico per stimare il numero di unità necessarie, e da queste vedere le risorse di memoria e calcolo richieste (moltiplicazioni, somme, divisioni float). Se le risorse richieste risultassero abbastanza basse potrebbe essere una via interessante (il procedimento è tutto qua).

Ciao Claudio, grazie per la risposta

in realtà (almeno al momento), il grafico 3d è molto molto semplice

una bozza in allegato

Sto continuando sulla strada suggerita da AmericanDreamers e sembra essere la migliore (che poi é la stessa suggerita da Guglielmo). Ho studiato tutta la documentazione e sembra che sia la strada più giusta.

Avendo una tabella da 20 x 20 ho pensato di crearmi 20 polinomi per ogni ascissa che coprono tutte le possibili ordinate poi per “la terza dimensione” , ogni volta che viene chiamata una diversa variabile di ascissa vado a fare il calcolo dei due polinomi più vicini (quello immediatamente precedente e quello immediatamente successivo) e ne faccio una semplice interpolazione lineare.

Cosa ne dite?

Grazi ancora per l’aiuto

Michele

Dacci maggiori dettagli,

Di che roba parliamo?

riassumento per adesso si tratta solo di aquisire un valore da un potenziometro diciamo (pedale acceleratore) e a calcolare il numero di giri di un motore termico attraverso un interrupt.

queste 2 sono le variabili di imput della tabella 2D, la variabile in uscita è la pressione di target che deve creare il turbocompressore, corrispondente per ogni combinazione di rpm / posizione pedale.

Il sistema acquisisce anche il segnale di pressione attuale e attraverso un PID (con il valore in uscita della tabella) comanda una valvola che è in grado di regolare la pressione stessa.

Spero di essere stato chiaro

grazie

Qui non si tratta di ottenere una curva di interpolazione ma una superficie.
L'ho fatto un paio di anni fa, ho trovato il codice qui
https://bitbucket.org/zunzuncode/zunzunsite3/src/master/
che però su Windows non gira a causa del fatto che il codice usa il fork.
C'è però il sito online
http://zunzun.com/
scegli una funzione interpolante dal menu 3D functions, ad esempio polyfunctional oppure polynomial (in questo caso hai ulteriori scelte)
Una volta scelto ti trovi nell'introduction. Dal menu a discesa selezioni il text editor e li compi i dati come nell'esempio.
Premi submit
Una volta ottenuta la curva puoi esportare la funzione sia in codice python che C++

zoomx questo è interessantissimo

la mia tabella è questa

0 0.5 0.6 0.7 0.8 0.9 1 1.2 1.3 1.4 1.5
0 0.5 0.6 0.7 0.8 0.9 1 1.2 1.4 1.4 1.5
0 0.6 0.7 0.8 0.9 1 1 1.3 1.4 1.4 1.5
0 0.7 0.8 0.9 0.9 1 1.1 1.4 1.4 1.5 1.5
0 0.8 0.8 1 1 1.1 1.2 1.4 1.4 1.5 1.5
0 0.7 0.8 1 1 1.1 1.2 1.4 1.4 1.5 1.5
0 0.6 0.8 1 1 1.1 1.2 1.4 1.4 1.5 1.5
0 0.5 0.8 1 1 1.1 1.2 1.4 1.4 1.5 1.5
0 0.5 0.8 1 1 1 1.1 1.4 1.4 1.5 1.5
0 0.5 0.8 0.9 0.9 0.9 1 1.3 1.4 1.5 1.5
0 0.4 0.7 0.8 0.8 0.9 1 1.2 1.2 1.4 1.5
0 0.3 0.6 0.7 0.7 0.9 1 1 1.1 1.3 1.4
0 0.3 0.5 0.6 0.6 0.8 0.9 1 1 1 1

con excel per ogni Y mi ero creato una funzione di intepolazione polinomiale del 5' ordine che mi soddisfaceva perchè rappresentava bene i valori.
Quindi mi ero definito 11 curve che avrei chiamato per ogni valore di X (ed interpolato tra di loro per valori di X intermedi)

Non sono molto ferrato in matematica ma mi sembra di capire che se dal tuo sito scelgo "3D" viene riassunto tutto in un'unica funzione.
Cosa mi consigli di utilizzare come intepolazione?

i dati devo inserirli nel text editor cosi come li ho inseriti qui mi sembra di capire giusto?

grazie

Lascia perdere Excel che non è nato per fare queste cose.
Si, otterrai un'unica funzione, sarebbe una superficie in XYZ dove X e Y sono i dati di ingresso e Y, la "quota" il calcolato.

Puoi scegliere la polinomiale anche li ma stai attento, di solito se interpola bene i dati aumentando l'ordine accade che fuori dall'intervallo i valori tendano a zero, cioè non puoi estrapolare.
Quindi proverei con la Full Cubic 3D