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 »

bearing skrev:
Al_Bundy skrev:
hawkan skrev:En grej som kan testas, om det ändå ska testas, är att byta alla "float" mot "double". Substitute all eller vad det kan heta.
Då vet du skillnad både i resultat och beräkningstid. Bara en idé, men jag hade gjort det. Jag hade för övrigt aldrig
gjort linear algebra med float, vad en sån åsikt nu kan vara värd.
Eller så testar ni att ta bort denna kod-rad.

Kod: Markera allt

*((ptr_q + j*n) + k) = *((ptr_q + j*n) + k) - *((ptr_r + i*n)+k)*(*((ptr_q + j*n) +i));
Den verkar inte göra någon skillnad för q-matrisen. :?

Det blir ju lite krångligt att förstå det där, med alla *-tecken överallt.

Du kan ju lägga in alla uttryck som liknar *((ptr_r + i*n)+k) i temporära variabler, och köra ovanstående beräkning på de temporära variablerna. Då kan du titta på och titta på varje sådant värde, och kontrollera att det stämmer, eller ifall någon av de där i,j,k,q,r, o.s.v är inknappat på rätt ställe.

Jag använder nästan aldrig variabler som är endast en bokstav, eftersom att det är så svårt att förstå koden och hitta buggar. Men matematisker gillar ju det.

Exakt! Som du ser så har jag bara skrivit av MATLAB-kod. Men jag tror att jag kanske måste hitta annan QR-kod för C.

Jag har ju använt mig av modifierad Gram-Schmidt, men kanske Householder är bättre. Den är mer avancerad.
bearing
Inlägg: 11670
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Matrisberäkningar med för STM32?

Inlägg av bearing »

Det blir kanske problem med dynamisk allokering om du en dag ska använda 100x100-matriser istället för 6x6, och inte tänkt på att dom inte får plats i minnet. Men jag tror inte heller att det är minnesallokeringen som kommer vara problemet.
sodjan
EF Sponsor
Inlägg: 43245
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Matrisberäkningar med för STM32?

Inlägg av sodjan »

Och sannolikt inte det som är problem just nu heller.
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 »

bearing skrev:Det blir kanske problem med dynamisk allokering om du en dag ska använda 100x100-matriser istället för 6x6, och inte tänkt på att dom inte får plats i minnet. Men jag tror inte heller att det är minnesallokeringen som kommer vara problemet.
Jag kommer alltid att använda 36x36 i mitt nuvarande program. Det är alltid samma matriser jag ska beräkna hela tiden.

Det jag gör för att verifiera om det fungerar eller inte är:
1. Beräkna i MATLAB
2. Skriv min C kod
3. Verifiera med valgrind i PC
4. Flytta över C-koden till STM32
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 »

sodjan skrev:Och sannolikt inte det som är problem just nu heller.
Jag tror att det är detta problem

https://math.stackexchange.com/question ... idt/771271
Both algorithms compute a QR factorisation of a matrix A, that is, A=QR. Due to rounding errors, we have A=Q~R~+E, where Q~ is no longer orthogonal (but close to in some sense). The residual E is not usually the problem, for both Householder and Gram-Schmidt (even the classic one), ∥E∥≤cϵ∥A∥, where c depends only on the dimension of A, ϵ is the machine precision. Here, ∥⋅∥ is some "rounding errors friendly" norm, e.g., any p-norm (usually 1, 2, or ∞).

The main difference is in the accuracy of the orthogonal factor. The Householder orthogonalisation gives Q~ which is almost orthogonal in the sense that ∥I−Q~TQ~∥≤cϵ. In the modified Gram-Schmidt, this "loss of orthogonality" is proportional to the condition number of A, that is, MGS yields ∥I−Q~TQ~∥≤cϵκ2(A) (note that the Q-factor from the classical Gram-Schmidt satisfies a similar bound with the condition number of A squared).

The difference between Householder and MGS is, roughly speaking, due to the fact that Householder computes the Q-factor as a product of accurate Householder reflections while MGS directly orthogonalises the columns of A.

By the way, both Householder and MGS compute an accurate R-factor R~ in the sense of backward error. For both, there is an (exact) orthogonal matrix Q^ and a residual matrix E^ (of course different for each) such that ∥E^∥≤cϵ∥A∥ and A=Q^R~+E^.
Det är ju Q-matrisen jag har problem med.
bearing
Inlägg: 11670
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Matrisberäkningar med för STM32?

Inlägg av bearing »

Innan du helt byter algoritm:
Al_Bundy skrev:

Kod: Markera allt

*((ptr_q + j*n) + k) = *((ptr_q + j*n) + k) - *((ptr_r + i*n)+k)*(*((ptr_q + j*n) +i));
Den verkar inte göra någon skillnad för q-matrisen. :?
Det betyder ju att produkten till höger är 0. Och det kan vara ett tecken på en bugg, att den läser från fel ställe i minnet, där värdena är noll typ. Så som jag sa, sätt varje faktor i temporära variabler och kolla att de får rätt värden, och inte alltid blir noll.

Eller så är det helt enkelt så att alltid en av de två faktorerna i produkten är noll. Och då ger ju ovanstående inte någon skillnad för Q. Men det antar jag inte är fallet.
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 lustiga är att om jag sätter en nolla här:

Kod: Markera allt

*((ptr_q + j*n) + k) = *((ptr_q + j*n) + k) - *((ptr_r + i*n)+k)*(*((ptr_q + j*n) +i))*0;
Så förändras inte Q, men R förändras. Så en bugg, kan det mycket väl vara.
Men jag tror bästa är att byta algoritm.
bearing
Inlägg: 11670
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: Matrisberäkningar med för STM32?

Inlägg av bearing »

R ändras ju på andra rader, så det är väl inte så konstigt.
Om R ändras på den där raden, ja då är något väldigt konstigt. Men det tror jag inte.

Hur som helst verkar det ju som att du inte är så intresserad av att söka efter ev. buggar, utan ska nu börja på ett nytt kapitel, trots många återstående frågetecken. Vore det inte klokt att ta reda på vad som händer i din kod, och varför den inte gör som den ska, innan du byter? Den lärdomen kommer nog att komma till användning senare när den nya algoritmen inte fungerar.
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 ska fixa ordning denna algoritm. Ett sista försök.

Ska dela upp algoritmen i flera delar och köra en del i taget. Då kanske man slipper C++. Vore skönt.
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 »

Efter jag fixar till qr.c filen så funderar jag på att skriva om projektet så att man bara allokerar minnet en gång och därmed får man återanvända matriserna.
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 var ingen bugg i qr.c, utan det var helt enkelt C's egna sätt att få fram decimaler. Jag har jämfört med Octave och det stämmer.

Det jag gjorde är att om jag har matrisen H så utfär jag bara denna ekvation:
\(H = QR\)

Där efter så multiplicerar jag ihop dem och då fick jag tillbaka mitt H. Bra!
\(Q*R\)

Jag testade även med SVD.
\(H = USV^{T}\)

Sedan satt jag ihop \(USV^{T}\) och fick mitt H, men det var rätt mycket fel i det H:et, vilket är normalt då det är SVD.

Så slutsatsen kan jag säga att jag hittar inga fel. Lite sämre avrundningar i C och C verkar vara dåligare på flyttal än vad GNU Octave är. Men annars så fungerar det.
hawkan
Inlägg: 3433
Blev medlem: 14 augusti 2011, 10:27:40

Re: Matrisberäkningar med för STM32?

Inlägg av hawkan »

Testade du med double? Det borde hjälpa precisionen i alla fall. Det är bara att gå tillbaka till float om du inte gillar 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 »

Japp! Det gjorde jag också. Samma resultat.

Jag säger så här. Mitt C-bibliotek är fullt godkänt för matrisberäkningar, men nackdelen med biblioteket är att den har svårt att hantera små små små tal typ e-7 och nedåt. Vad det kan bero på tror jag det har med själva C programmeringsspråk att göra. Om C++ skulle göra bättre ifrån sig, vet jag inte. Jag tvivlar lite på det faktiskt. Rätta mig om jag har fel.

Annars funderar jag på att skriva om strukturen på biblioteket så att man bara allokerar matriser EN gång. Där efter återanvänder man dem. Vad tror ni om det? Tror ni det skulle vara bra om jag anpassar det för c89 standard? Eller tjänar jag något på det?

Nu blev jag sugen på lite debatt här. Motivera VARFÖR jag inte ska använda C++ i STM32? Alla motiveringar accepteras.
sodjan
EF Sponsor
Inlägg: 43245
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Matrisberäkningar med för STM32?

Inlägg av sodjan »

C ska inte ha några problem att hantera flyttal inom de specificerade ramarna för
den aktuella flyttals typen (float, double, whatever). e-7 är ju inte speciellt
litet för i princip alla flyttals typer.

Jag tror mer på att det är något temporärt värde inne i formlerna som sticker iväg
uppåt eller nedåt.

Så det borde inre ha någonting med C som språk i sig. Kanske med någon implementering
av flyttalsoperationer i ett libc eller liknande, men om rutinerna använder en FPU så borde
de bara skicka samma FPU instruktioner oavsett programmeringsspråk.
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 »

Så kan det vara. Men med tanke på att jag delar upp H = QR och sedan Q*R -> H och jag gör samma sak med SVD där jag sätter H = USV^T och sedan sätter jag U*S*V^T -> H, med lite avrundingar.

Jag kör samma algoritmer i Octave och dem visar samma. Skillnaden mellan i C och Octave är att precisionen är bättre i Octave än i C. Jag mätte upp just nu. Om precisionen är e-10 i C för SVD så är precisionen e-18 i Octave för just samma tal. Vi alla vet att e-10 är riktigt litet, men det kan göra påverkningar ändå.

Vad tror du Sojjan? Kan det vara så att om jag initialiserar matriserna bara en gång och sedan återanvänder jag dem. Då kan det bli bättre resultat?
Skriv svar