Matrisberäkningar med för STM32?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

Mr Andersson skrev:
Icecap skrev:Men om du kör med fasta storlekar - men att storleken kan ändras med projektet - är det ju bara att deklarera storleken i en deklaration och sedan låta hela programmet ta del av den deklaration.
Jo det här är ju det smidigaste och stabilaste. Men jag får intrycket att han vill ha ett generiskt bibliotek där storleken anges vid körning. (Med reservation för att jag kan ha misstolkat syftet) :)
Om jag har en matris A med storleken 5x5 och sedan stoppar jag in den i funktionen solve(matrix* a) så bildas der typ en temporär array med samma storlek som matris A.

Är matris A 7x7 så ändras den temporära arrayen.

Är detta OK att göra?
Användarvisningsbild
säter
Inlägg: 35216
Blev medlem: 22 februari 2009, 21:16:35
Ort: Säter

Re: Matrisberäkningar med för STM32?

Inlägg av säter »

Icecap skrev:På det vis har jag "standard" filer som slår på kommunikation med RTC, EEPROM, 1-Wire®, RS232 A & B, RS485, korthållsradio, WLAN, LAN, PWM för displayintensitet och vad jag annars kan behöva.
Är det tillåtet att ställa en rudimentär fråga?
Rick81
Inlägg: 755
Blev medlem: 30 december 2005, 13:07:09

Re: Matrisberäkningar med för STM32?

Inlägg av Rick81 »

Du sätter ju #define på max storleken tex 100x100 sen sätter du ju storlek beroende på operation 5x5, 7x7 eller vad som behövs.

Notera att Halbiblioteket har samma #define på olika filer som Icecap och jag kör även liknande på mina projekt så helt dumt är det inte.
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Matrisberäkningar med för STM32?

Inlägg av Icecap »

säter: såklart.

Men lite generellt:
#define Something 1
kan användas som t.ex.:
#if Something
...
#else
...
#endif

Men Om man skriver:
#define Something
har Something inget värde! Då kan man skriva:
#ifdef Something [eller #if defined(Something)]
...
#else
...
#endif

Men Something kan båda vara "tilldelad" ett värde (#define Something 1) OCH man kan kolla OM Something överhuvudet är definierat.

På detta vis kan man slå på "funktioner" vid att definiera ATT Something finns och sedan, i funktionen, använda värdet.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

Vad tror ni om denna kod?
Här kommer jag att ha olika matriser på a, q och r. Men dessa matriser allokeras bara EN gång.

Kod: Markera allt

void cut_internal_qr(matrix* a, int start_n, int stop_n, int start_m, int stop_m, float* b, int out_columns);
float dot_internal_qr(float* a, float* b, int n);
float norm_internal_qr(float* a, int n);

/*===========================================================================
 * qr
 * Get Q and R matrix from matrix by using Modified Gram-Schmidt method
 * Input: Matrix
 * Return: void
 * Works: OK
 *=========================================================================*/
void qr(matrix* a, matrix* q, matrix* r) {

	// Get info about matrix a
	int n = a->row;
	int m = a->column;
	float* ptr = a->data;

	// Get data
	float* ptr_q = q->data;
	float* ptr_r = r->data;

	float c1[n];
	float c2[n];
	memset(c1, 0, sizeof(c1));
	memset(c2, 0, sizeof(c2));


	for(int k = 0; k < m; k++){
		// Insert vector
		for(int j = 0; j < n; j++)
			*((ptr_q + j*n) + k) = *((ptr + j*n) + k);

		// Do the dot product
		for(int i = 0; i < k; i++){
			cut_internal_qr(q, 0, n-1, i, i, c1, 1);
			cut_internal_qr(q, 0, n-1, k, k, c2, 1);
			*((ptr_r + i*m)+k) = dot_internal_qr(c1, c2, n);

			// Insert vector again
			for(int j = 0; j < n; j++)
				*((ptr_q + j*n) + k) = *((ptr_q + j*n) + k) - *((ptr_r + i*m)+k)*(*((ptr_q + j*n) +i));

		}

		cut_internal_qr(q, 0, n-1, k, k, c1, 1);
		*((ptr_r+k*m)+k) = -norm_internal_qr(c1, n); // Important with negative

		// Insert vector again
		for(int j = 0; j < n; j++){
			if(*((ptr_r + k*m) + k) ==  0){
				*((ptr_r + k*m) + k) = pow(2.2204, -16); // Same as eps command in MATLAB
			}
			*((ptr_q + j*n) + k) = (*((ptr_q + j*n) + k)) / (*((ptr_r + k*m) + k));
		}

	}

}

void cut_internal_qr(matrix* a, int start_n, int stop_n, int start_m, int stop_m, float* b, int out_columns) {

	int in_columns = a->column;
	float* data = a->data + start_n * in_columns + start_m;

	// Instead of having two for loops, we just copy the whole row at once.
	for (int i = start_n; i < stop_n + 1; i++) {
		memcpy(b, data, sizeof(float) * out_columns);
		b += out_columns;
		data += in_columns;
	}

}

float dot_internal_qr(float* a, float* b, int n) {

	// Reset
	float sum = 0;

	// Multiply each row
	for (int i = 0; i < n; ++i) {
		sum += (*(a + i)) * (*(b + i));
	}
	return sum;

}

float norm_internal_qr(float* a, int n) {

	float sum = 0; // Initial
	for (int i = 0; i < n; i++)
		sum += (*(a + i)) * (*(a + i));
	return sqrt(sum);
}




/* MATLAB CODE
 * function [Q,R] =  mgs(X)
    % Modified Gram-Schmidt.  [Q,R] = mgs(X);
    % G. W. Stewart, "Matrix Algorithms, Volume 1", SIAM, 1998.
    [n,p] = size(X);
    Q = zeros(n,p);
    R = zeros(p,p);
    for k = 1:p
        Q(:,k) = X(:,k);
        for i = 1:k-1
            R(i,k) = Q(:,i)'*Q(:,k);
            Q(:,i)'*Q(:,k)
            Q(:,k) = Q(:,k) - R(i,k)*Q(:,i);
        end
        R(k,k) = -norm(Q(:,k))';
        Q(:,k) = Q(:,k)/R(k,k);
    end
end
 */
Användarvisningsbild
säter
Inlägg: 35216
Blev medlem: 22 februari 2009, 21:16:35
Ort: Säter

Re: Matrisberäkningar med för STM32?

Inlägg av säter »

Icecap skrev:säter: såklart.
På det vis har jag "standard" filer som slår på kommunikation med RTC, EEPROM, 1-Wire®, RS232 A & B, RS485, korthållsradio, WLAN, LAN, PWM för displayintensitet och vad jag annars kan behöva.
Är det här funktioner som du har skrivit själv?
Eller är det sådant du har hittat på nätet?
Användarvisningsbild
Icecap
Inlägg: 26632
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Matrisberäkningar med för STM32?

Inlägg av Icecap »

Säter: Det är jag, 1636 sidor datablad och "några timmar" och lite testande.
Lägg till datablad för varje enhet och en handfull kunnande om hårdvara och vi är i mål.
Användarvisningsbild
säter
Inlägg: 35216
Blev medlem: 22 februari 2009, 21:16:35
Ort: Säter

Re: Matrisberäkningar med för STM32?

Inlägg av säter »

Tack för svaret.
Det var som jag anade.
guckrum
Inlägg: 1903
Blev medlem: 19 juni 2012, 09:04:27
Ort: Lund

Re: Matrisberäkningar med för STM32?

Inlägg av guckrum »

Vad tror ni om denna kod?
Hur testar du? I alla fall jag drar mig å det längsta för att sitta och läsa
kod som eventuellt inte är ordentligt testad - datorer är bättre på sådant
och jag får tid över till annat.

Saknar du testning kan ett förslag vara att skapa filer med in- respektive
förväntad utdata via Octave, Matlab eller annat program som du tror räknar
"rätt", och strömma det genom ditt program. Sitter du på en Matlablicens
kan du använda mex-interfacet för att integrera din C-kod direkt i Matlab
och köra den parallellt med Matlab-referenskoden. (Sedan är det en mental
övning att fundera ut vilka testfall som exciterar koden bäst.)

En grej:

Kod: Markera allt

pow(2.2204, -16); // Same as eps command in MATLAB
Jag tror att pow() är exponentiering ("man 3 pow"), men gissar att du vill
beskriva 2.2204e-16, vilket är något helt annat. Och i vilket fall så bör
du använda färdiga defines för typers max och minvärden, det minskar
risken för fel och ser till att konstanten blir rätt oavsett målplatform.
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

Tack! Jag ska lägga till denna i en define.

Men hur blir det med alla dessa arrayer som inte allokeras med malloc? Är detta OK att använda arrayer i inbyggda system?
När man anropar en funktion som har en array, så skapas det minne för just denna array? När man "lämnar" funktionen, så frigörs minnet på arrayen. Eller hur?
Rick81
Inlägg: 755
Blev medlem: 30 december 2005, 13:07:09

Re: Matrisberäkningar med för STM32?

Inlägg av Rick81 »

Skapar du arrayer lokalt i en funktion så läggs de normalt på stacken.

Deklarar du dem med static eller deklarer dem utanför funktionen så läggs i de i statiskt RAM.


Jag skulle rekommender att du göra några arrayer som statiska som du sedan använder.

ex:

Kod: Markera allt

#define MATRIX_SIZE 100

matrix a[MATRIX_SIZE][MATRIX_SIZE];
matrix b[MATRIX_SIZE][MATRIX_SIZE];
matrix c[MATRIX_SIZE][MATRIX_SIZE];


void main()
{
	a = CreateMatrix(5,5);	//5x5 matris
	b = CreateMatrix(7,7);	//5x5 matris
	c = svd(a, b);		// helt tokigt men du fattar principen
	PrintMatrix(c);
}
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

Det blir liksom svårt det där. Hmmm...hur ska man göra?

Jag vill ju att stacken inte ska "röras" under körningen för att inte riskera att "misshandla" minnet. Men samtidigt så vill jag att biblioteket ska vara enkelt att använda där man kan återanvända matriserna.

Hmm...jag tror jag fick en ide!

Vi säger att jag har en funktion som heter foo(matrix* a, matrix* b). Denna funktion använder sig också av en funktion som heter cut(float* a, int i, int j) typ. Där float* a är en matris och den deklareras i just funktionen cut. Då kanske man ska deklarera foo som foo(matrix* a, matrix* b, float* a) typ?

Biblioteket blir svårare att använda, men istället så hålls stacken statiskt. Eller vad tycker ni?

Edit: Men vänta nu lite! Blir det inte samma sak för vanliga variabler? Min stack kommer aldrig vara statisk alltså!
Rick81
Inlägg: 755
Blev medlem: 30 december 2005, 13:07:09

Re: Matrisberäkningar med för STM32?

Inlägg av Rick81 »

Läste du inte mitt förslag? Eller vad var fel med det?
Användarvisningsbild
Al_Bundy
Inlägg: 2889
Blev medlem: 11 september 2012, 23:59:50
Ort: The U.S - Chicago
Kontakt:

Re: Matrisberäkningar med för STM32?

Inlägg av Al_Bundy »

Jag har redan gjort ditt förslag för 3 dagar sedan. Det är endast arrayer i funktionerna som jag är nyfiken på. Är det OK om man har arrayer som deklareras inuti funktioner? Tydligen så var svaret NEJ. Men hur blir det då med variabler? Dessa läggs på stacken också.
hawkan
Inlägg: 3446
Blev medlem: 14 augusti 2011, 10:27:40

Re: Matrisberäkningar med för STM32?

Inlägg av hawkan »

Jag tror du föreslagit en av de klassiska källorna till buggar i program i C.
Du får inte använda minne från stacken i cut - det blir fel.

Det är inget problem att använda lokala variabler, lokalt deklarerade matriser.
De är bara poff borta när du lämnar funktionen.
Problem kan uppstå om du har rekursiva funktioner med stora djup, det kan förbruka
minnet på stacken.
Håller man sej till grunda anropskedjor (call stack) skulle jag föredra att ha lokala
variabler för de som inte behöver vara tillgängligt globalt.
Skriv svar