Matrisberäkningar med för STM32?
Re: Matrisberäkningar med för STM32?
Tanken är att man ska först göra sina beräkningar i MATLAB. Där efter ska man kunna använda likadana kommandon i C för att utföra sin MATLAB kod, fast i C.
Jag har tänkt på detta. Jag har dock inte lagt till det än.
Jag har tänkt på detta. Jag har dock inte lagt till det än.
-
- Inlägg: 1407
- Blev medlem: 29 januari 2011, 21:06:30
- Ort: Lapplandet
Re: Matrisberäkningar med för STM32?
1) Använd memcpy, mycket snabbare än att kopiera individuella element.Al_Bundy skrev:En fråga! Om jag ska kopiera värden från en matris till en annan, då skriver jag denna kod.
...
Där eye(n) retunerar en identitetsmatris. Måste jag radera denna eye(n) efter jag har "kört klart" copyval(matrix* a, matrix* b) ? Eller beror det på vilken kompilator jag använder? Just nu är det C11.
2) Radering; Det beror på hur du skapar matrisen, inte vilken kompilator du har. Allt som är malloc'erat ska frigöras när du inte ska använda det mer. Men med det sagt så är ju identitetsmatriser både konstanta (ändras aldrig) och väldigt vanliga, så skapa dem en gång vid uppstart och hänvisa till samma matris varje gång.
Re: Matrisberäkningar med för STM32?
Okej. Jag ska använda memcpy. Så här blev det
Ja. Så fort jag kopierar, så gör jag alltså en ny malloc på en matris som jag fyller på med värden. Sedan retunerar jag tillbaka denna matris. Jag har svårt för att radera , i samma funktion, det jag ska retunera tillbaka. 
Istället för att skapa en matris som jag har som argument i en funktion. Så skapar jag matrisen direkt som argument. Matrisen är allokerad med minne. Så jag får inte tillbaka den.
Kod: Markera allt
void copyval(matrix*a, matrix* b){
b->data = a->data; // Matris a och matrix b har samma dimension och samma datatyp.
/*
int n = b->row;
int m = b->column;
float* ptr_a = a->data;
float* ptr_b = b->data;
// copy all values from matrix a to matrix b
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
*(ptr_b++) = *(ptr_a++);
}
}
*/
}

Istället för att skapa en matris som jag har som argument i en funktion. Så skapar jag matrisen direkt som argument. Matrisen är allokerad med minne. Så jag får inte tillbaka den.
Re: Matrisberäkningar med för STM32?
Al, mitt förslag är att alla funktioner tar in matrix* som argument oavsett om de är in eller ut-argument till funktionen. Då lägger du ansvaret på den som anropar funktionen att allokera minnet bäst hur den vill. Nackdelen är att att den som anropar måste ha koll på dimensionen av eventuella utargument. Behöver en funktion mellanlagra resultat kan du som sagt förallokera matriser till detta eller så börjar du med att allokera dem dynamiskt och optimerar senare.
Börja skissa på header-filen för dina funktioner och torrhacka ett program som använder dina funktioner så ser du om API blir smidigt eller vilka kompromisser du behöver göra.
Kod: Markera allt
// create gör malloc, sedan behöver du en destroy också.
matrix* x = create(3, 3);
matrix* y = create(1, 3);
matrix* z = create(3,3);
// Set values in x
set_scalar(3, y);
z = multiply(x, y, z); // här måste du även bestämma dig för om utargumentet får vara ett av inargumenten.
Re: Matrisberäkningar med för STM32?
Just nu försöker jag bara få det att fungera. Men samtidigt vill jag inte göra dubbeljobb. Så optimering lämnar jag till sist.
Vi säger att din kod hade sett ut så här
Hur hade du gjort nu? Du får matris z tillbaka. Men i argumenten så har du skapat tre matriser också.
Vi säger att din kod hade sett ut så här
Kod: Markera allt
// Set values in x
set_scalar(3, y);
matrix* z = multiply(create(3,3), create(1,3), create(3,3)); // här måste du även bestämma dig för om utargumentet får vara ett av inargumenten.
Re: Matrisberäkningar med för STM32?
Vad har du för nytta av att multiplicera tre oinitierade matriser?
Re: Matrisberäkningar med för STM32?
I C kan man göra:
Och då har du inte slavat bort något minne förutsatt du kör destroy() på dem senare.
Personligen tycker jag det är otydlig kod att ha tilldelningar inuti uttryck.
Sedan är ju detta kanske inte det bästa exemplet som AndLi påpekar såvida man inte kan initialisera matris x men koden blir ju ännu grötigare då.
Kod: Markera allt
matrix* x;
matrix* y;
matrix* z = multiply(y = set_scalar(3, create(1,3)), x = create(1,3), create(3,3));
Personligen tycker jag det är otydlig kod att ha tilldelningar inuti uttryck.
Sedan är ju detta kanske inte det bästa exemplet som AndLi påpekar såvida man inte kan initialisera matris x men koden blir ju ännu grötigare då.
Re: Matrisberäkningar med för STM32?
I C går det rätt bra att dölja att man jobbar med pekare och kan ha upplevelsen av att man jobbar med objekt.
Matrix_Example.c
Matrix_Example.h
Jag kommer inte ihåg hur det är nu med C++ och överlagring. Skulle man kunna få till en överlagrad operator som gör att man kan ha matrismultiplikation av stilen A * B * C? Jag ser inte vad hindret skulle vara.
Matrix_Example.c
Kod: Markera allt
#include "Matrix_Example.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
Matrix_Element GetMatrixElement(Matrix SourceMatrix, uint32_t Row, uint32_t Column)
{
return SourceMatrix->MatrixPosition[Row][Column];
}
Matrix EmptyMatrix(uint32_t Rows, uint32_t Columns)
{
uint32_t Row;
Matrix_Element **NewMatrixArray =
(Matrix_Element **) malloc(sizeof(Matrix_Element *) * Rows);
for(Row = 0; Row < Columns; Row++)
{
NewMatrixArray[Row] = (Matrix_Element *) malloc(sizeof(Matrix_Element) * Columns);
}
Matrix NewMatrix = (Matrix) malloc(sizeof(Matrix_Type));
NewMatrix->MatrixPosition = NewMatrixArray;
NewMatrix->Rows = Rows;
NewMatrix->Columns = Columns;
return NewMatrix;
}
Matrix IdentityMatrix(uint32_t Rows, uint32_t Columns)
{
Matrix NewMatrix = EmptyMatrix(Rows, Columns);
uint32_t Row_Index;
uint32_t Column_Index;
for(Row_Index = 0; Row_Index < Rows; Row_Index++)
{
for(Column_Index = 0; Column_Index < Columns; Column_Index++)
{
if(Row_Index == Column_Index)
{
NewMatrix->MatrixPosition[Row_Index][Column_Index] = 1.0f;
}
}
}
return NewMatrix;
}
void PrintMatrix(Matrix MatrixToPrint)
{
uint32_t Row_Index;
uint32_t Column_Index;
for(Row_Index = 0; Row_Index < MatrixToPrint->Rows; Row_Index++)
{
for(Column_Index = 0; Column_Index < MatrixToPrint->Columns; Column_Index++)
{
printf("%0.3f ", GetMatrixElement(MatrixToPrint, Row_Index, Column_Index));
}
printf("\n");
}
printf("\n");
}
int main()
{
Matrix My_Matrix = IdentityMatrix(36, 36);
PrintMatrix(My_Matrix);
return 0;
}
Kod: Markera allt
#include "stdint.h"
typedef float Matrix_Element;
typedef struct
{
Matrix_Element** MatrixPosition;
uint32_t Rows;
uint32_t Columns;
} Matrix_Type;
typedef Matrix_Type *Matrix;
Re: Matrisberäkningar med för STM32?
Vektorisering.AndLi skrev:Vad har du för nytta av att multiplicera tre oinitierade matriser?
mankan skrev:I C kan man göra:Och då har du inte slavat bort något minne förutsatt du kör destroy() på dem senare.Kod: Markera allt
matrix* x; matrix* y; matrix* z = multiply(y = set_scalar(3, create(1,3)), x = create(1,3), create(3,3));
Personligen tycker jag det är otydlig kod att ha tilldelningar inuti uttryck.
Sedan är ju detta kanske inte det bästa exemplet som AndLi påpekar såvida man inte kan initialisera matris x men koden blir ju ännu grötigare då.
Jo. Men kan jag göra som jag gjorde ovan, utan att det blir problem? Eller måste jag "dela" upp det och sedan köra destroy på de övriga? I mitt fall heter det "freeMatrix(matrix* a)" och koden ser ut så här.
Kod: Markera allt
void freeMatrix(matrix* m) {
if (m != NULL) {
if (m->data != NULL) {
free(m->data);
m->data = NULL;
}
free(m);
m = NULL;
}
}
Senast redigerad av Al_Bundy 15 januari 2019, 19:25:19, redigerad totalt 1 gång.
Re: Matrisberäkningar med för STM32?
Jag har gjort liknande, men vad mycket C-kod du skrev för just dettaShimonu skrev:I C går det rätt bra att dölja att man jobbar med pekare och kan ha upplevelsen av att man jobbar med objekt.
Matrix_Example.cMatrix_Example.hKod: Markera allt
#include "Matrix_Example.h" #include <stdlib.h> #include <string.h> #include <stdio.h> Matrix_Element GetMatrixElement(Matrix SourceMatrix, uint32_t Row, uint32_t Column) { return SourceMatrix->MatrixPosition[Row][Column]; } Matrix EmptyMatrix(uint32_t Rows, uint32_t Columns) { uint32_t Row; Matrix_Element **NewMatrixArray = (Matrix_Element **) malloc(sizeof(Matrix_Element *) * Rows); for(Row = 0; Row < Columns; Row++) { NewMatrixArray[Row] = (Matrix_Element *) malloc(sizeof(Matrix_Element) * Columns); } Matrix NewMatrix = (Matrix) malloc(sizeof(Matrix_Type)); NewMatrix->MatrixPosition = NewMatrixArray; NewMatrix->Rows = Rows; NewMatrix->Columns = Columns; return NewMatrix; } Matrix IdentityMatrix(uint32_t Rows, uint32_t Columns) { Matrix NewMatrix = EmptyMatrix(Rows, Columns); uint32_t Row_Index; uint32_t Column_Index; for(Row_Index = 0; Row_Index < Rows; Row_Index++) { for(Column_Index = 0; Column_Index < Columns; Column_Index++) { if(Row_Index == Column_Index) { NewMatrix->MatrixPosition[Row_Index][Column_Index] = 1.0f; } } } return NewMatrix; } void PrintMatrix(Matrix MatrixToPrint) { uint32_t Row_Index; uint32_t Column_Index; for(Row_Index = 0; Row_Index < MatrixToPrint->Rows; Row_Index++) { for(Column_Index = 0; Column_Index < MatrixToPrint->Columns; Column_Index++) { printf("%0.3f ", GetMatrixElement(MatrixToPrint, Row_Index, Column_Index)); } printf("\n"); } printf("\n"); } int main() { Matrix My_Matrix = IdentityMatrix(36, 36); PrintMatrix(My_Matrix); return 0; }
Jag kommer inte ihåg hur det är nu med C++ och överlagring. Skulle man kunna få till en överlagrad operator som gör att man kan ha matrismultiplikation av stilen A * B * C? Jag ser inte vad hindret skulle vara.Kod: Markera allt
#include "stdint.h" typedef float Matrix_Element; typedef struct { Matrix_Element** MatrixPosition; uint32_t Rows; uint32_t Columns; } Matrix_Type; typedef Matrix_Type *Matrix;

Min print ser ut så här.
Kod: Markera allt
void printMatrix(matrix* m) {
float* ptr = m->data;
for (int i = 0; i < m->row; i++) {
for (int j = 0; j < m->column; j++) {
printf(" %9.6f", *(ptr++));
}
printf("\n");
}
}
Varför deklarerade du uint32_t utanför forloopen?
Kod: Markera allt
uint32_t Row;
for(Row = 0; Row < Columns; Row++)
{
NewMatrixArray[Row] = (Matrix_Element *) malloc(sizeof(Matrix_Element) * Columns);
}
Re: Matrisberäkningar med för STM32?
Får man inte ut brus av att multiplicera brus med varandra?Al_Bundy skrev:Vektorisering.AndLi skrev:Vad har du för nytta av att multiplicera tre oinitierade matriser?
Re: Matrisberäkningar med för STM32?
Vad grötig och oläsbar din kod är. Våra funktioner för att skriva ut en matris ser ju näst intill identiska ut. Var har jag skrivit mycket kod?Al_Bundy skrev:
Jag har gjort liknande, men vad mycket C-kod du skrev för just detta![]()
Min print ser ut så här.Kod: Markera allt
void printMatrix(matrix* m) { float* ptr = m->data; for (int i = 0; i < m->row; i++) { for (int j = 0; j < m->column; j++) { printf(" %9.6f", *(ptr++)); } printf("\n"); } }
Det är av vana efter att ha jobbat med gamla versioner av C där det är tvunget. Du ser, C utvecklas också.Al_Bundy skrev: Varför deklarerade du uint32_t utanför forloopen?
Kod: Markera allt
uint32_t Row; for(Row = 0; Row < Columns; Row++) { NewMatrixArray[Row] = (Matrix_Element *) malloc(sizeof(Matrix_Element) * Columns); }
-
- Inlägg: 1407
- Blev medlem: 29 januari 2011, 21:06:30
- Ort: Lapplandet
Re: Matrisberäkningar med för STM32?
Verkar som att Al på något sätt tror att antal kodlinjer är lika med prestanda.
Vektorisering har ingenting att göra med om saker är på samma rad eller inte. Dessutom har cm4f varken SIMD eller superskalär arkitektur så det är helt meningslöst att försöka vektorisera.
Vektorisering har ingenting att göra med om saker är på samma rad eller inte. Dessutom har cm4f varken SIMD eller superskalär arkitektur så det är helt meningslöst att försöka vektorisera.
Re: Matrisberäkningar med för STM32?
Okej! Det kanske är annat när det är lågnivåspråk.
Men hur var det med att ha ett allokerad argument i en funktion? Gör det något? Raderas den automatiskt efter funktionen har retunerats?
Men hur var det med att ha ett allokerad argument i en funktion? Gör det något? Raderas den automatiskt efter funktionen har retunerats?
Re: Matrisberäkningar med för STM32?
Ursäkta tjatet:
En funktions argument läggs på stacken.
Vadå allokerat argument i en funktion?mankan skrev:Det är hög tid att du lär dig hur stack och heap fungerar oavsett programspråk.
En funktions argument läggs på stacken.