Sida 4 av 8
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 17:47:55
av bearing
DanielM skrev:Alltså jag menar att om jag har en for-loop som jag itererar +1 mer än vad en array har för element. Då borde väll jag få ett felmeddelande?
Upprepar: Nej. (Skrev samtidigt.)
På ett operativssystem kan det hända att du får segmenteringsfel. "Programmet har gjort en förbjuden åtgärd". Men det är inte garanterat. Beror på hur många iterationer fel loopen går. Mest sannolikt är att programmet bara börjar läsa/skriva nästa array i minnet.
På en mikrokontroller med minneshanterare kan du också få segmenteringsfel ifall du ställer in minneshanteraren enligt hur du vill ha det.
Du programmerar ju "bare bones". Finns inget som räddar dig. Vad som helst kan hända om programmet skriver till fel minne. Inklusive att din radiostyrda bil fäller käppen för en gammal dam, och kör ut över en kajkant.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 17:49:39
av AndLi
DanielM skrev:Alltså jag menar att om jag har en for-loop som jag itererar +1 mer än vad en array har för element. Då borde väll jag få ett felmeddelande?
Vad får dig att tro det?
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 17:57:20
av sodjan
Varför man kan tro det?
Därför att i de flesta programmeringsspråk är det inbyggt.
Det är C som är undantaget i detta fall.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 18:04:20
av bearing
Sen finns det ju språk där variabeln förstoras automatiskt så att den alltid rymmer det man stoppar i den.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 19:14:33
av DanielM
sodjan skrev:Varför man kan tro det?
Därför att i de flesta programmeringsspråk är det inbyggt.
Det är C som är undantaget i detta fall.
Alltså om jag har en array som rymmer 5 element och sedan initsaliserar jag den med 6 element.
Då varnar min IDE och markerar felet.
Men jag har aldrig fått någon varning om jag kör en funktion som har en for-loop i sig där for loppen skriver ut varje tal + ett extra element som inte finns.
Däremot har jag varit med om att Valgrind har pekat på fel i if-satser. Kanske borde detta göra en enkel simulering med Valgrind igen.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 19:18:43
av bearing
Vid kompileringen kan vissa fel upptäckas. Men inte under körning. Därför att den enda info som sparas om en array är dess placering i minnet. Längden på arrayen sparas inte.
Och om man ska gå in lite mer tekniskt, fungerar en array bara som en pekare. Den pekar på ett minnesutrymme som allokerats vid länkningen. Och pekaren är bara en variabel som innehåller ett nummer. Numret är adressen till starten på detta minnesutrymme.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 20:51:57
av DanielM
Itererade en 4-array i en for-loop nu där loopen itererade 6 gånger. Inga felmeddelanden från IDE:n eller Valgrind.
Kod: Markera allt
int main() {
// Matrix A
float A[4*4] = {0.649587, 0.320520, 0.274275, 0.821053,
0.424608, 0.996594, 0.638315, 0.636367,
0.719499, 0.017284, 0.321835, 0.060467,
0.859543, 0.243554, 0.402577, 0.753847};
// Vector b
float b[4] = {0.091799,
0.202273,
0.269783,
0.580578};
// Do backwardsubstitution
clock_t start, end;
float cpu_time_used;
start = clock();
backwardsubstitution(A, b, 4); // This ONLY prepare A, b to be solved linsolve
end = clock();
cpu_time_used = ((float) (end - start)) / CLOCKS_PER_SEC;
printf("\nTotal speed was %f\n", cpu_time_used);
// Print A and b
printf("A\n");
print(A, 4, 4);
printf("b\n");
print(b, 4, 1);
for(int i = 0; i <= 5; i++)
printf("b[%i] = %f\n", i, b[i]);
return EXIT_SUCCESS;
}
Skriver ut:
Kod: Markera allt
Total speed was 0.000003
A
0.649586975574493408 0.320520013570785522 0.274275004863739014 0.821053028106689453
0.000000029802322388 0.787083387374877930 0.459032863378524780 0.099678814411163330
0.000000012787971571 0.000000000000000000 0.215008884668350220 -0.806180655956268311
-0.000000001784709713 0.000000000000000000 0.000000000000000000 0.233807533979415894
b
0.091798998415470123
0.142267808318138123
0.229150220751762390
0.337253630161285400
b[0] = 0.091799
b[1] = 0.142268
b[2] = 0.229150
b[3] = 0.337254
b[4] = 0.649587 <- Från A
b[5] = 0.320520 <- Från A
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 21:25:44
av DanielM
Testade nu med Valgrind SGCheck och nu kan jag hitta fel i stacken på koden ovan. Den skriver ut exakt vad som händer och räknar fel.
Men alla andra C program som jag har skrivit för numeriska beräkningar:
- QP-faktorisering
- Singular Value Decompotision med Golub & Reins algorithm
- Singular Value Decompotision med Jacobi One-Side rotation
- LU-faktorisering
- Tikhonov regularization
- Choleksy faktorisering
- Backward subsitution och forward substitution
- Determinant
- Lyapunov
0 fel från Valgrind!
Känner att jag redan hör Unreal Tournament 1999 segerlåtar i huvudet mitt.

Jag har aldrig använt det verktyget förut eller ens kollat om jag har skrivit rätt kod.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 22:24:02
av bearing
Precis, resultatet blev ju exakt som jag skrev.
Är det inte meningen att man ska skriva in förväntade resultat någonstans i det där programmet Valgrind?
Blir ju inte mycket till verifiering annars. Det blir som att en biltillverkares testförare kör bilen från 0-100 utan att mäta tiden tiden för accelerationen och jämföra med kravet.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 23:02:09
av Palle500
DanielM skrev:Alltså jag menar att om jag har en for-loop som jag itererar +1 mer än vad en array har för element. Då borde väll jag få ett felmeddelande?
Du löser detta genom att låta en funktion hantera din array och således även felhanteringen. Och det är den funktionen som alla andra funktioner skall anropa istället för att gå rakt på din array.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 4 mars 2020, 23:23:08
av DanielM
bearing skrev:Precis, resultatet blev ju exakt som jag skrev.
Är det inte meningen att man ska skriva in förväntade resultat någonstans i det där programmet Valgrind?
Blir ju inte mycket till verifiering annars. Det blir som att en biltillverkares testförare kör bilen från 0-100 utan att mäta tiden tiden för accelerationen och jämföra med kravet.
Vadå exakt som du skrev?
Jag har skrivit flera hundra rader C kod och Valgrind kunde inte hitta ett enda fel på koden, alltså minnesläcka i stacken.
Däremot om jag medvetet gjorde felet så säger den till.
Här är ett exempel på One-Side SVD med Jacobi rotation. Vad kan man använda denna till då?
Jo, har man mycket mätdata som man samlar i en kvadratisk matris så kan man göra regression, systemidentifiering eller klassificering.
Har man en icke-kvadratisk matris så måste man gå på en QR-metod. Men QR-metoden är dyr och tar mycket tid. Då är det bättre med Golub och Reins algoritm, vilket är de fakto standard. One-Side SVD algorithmen är extremt snabb, men passar bara kvadratisk matriser.
Kod: Markera allt
void svd_jacobi_one_sided(float *A, int row, float *U, float *S, float *V) {
// i and j are the indices of the point we've chosen to zero out
float al, b, c, l, t, cs, sn, tmp, sign;
int i, j, p, k;
// Create the identity matrix
memset(U, 0, row*row*sizeof(float));
memset(V, 0, row*row*sizeof(float));
memset(S, 0, row*sizeof(float));
for(i = 0; i < row; i++){
*(U + row*i + i) = 1;
*(V + row*i + i) = 1;
}
// Apply MAX_ITERATION_COUNT_SVD times. That should be good enough
for (p = 0; p < MAX_ITERATION_COUNT_SVD; p++) {
// For all pairs i < j
for (i = 0; i < row; i++) {
for (j = i + 1; j < row; j++) {
al = b = c = l = t = cs = sn = tmp = sign = 0.0;
// Find the 2x2 submatrix
for (k = 0; k < row; k++) {
al += *(A + row*k + i) * *(A + row*k + i);
b += *(A + row*k + j) * *(A + row*k + j);
c += *(A + row*k + i) * *(A + row*k + j);
}
// Compute Jacobi rotation
l = (b - al) / (2.0 * c);
sign = 1.0;
if (l < 0.0)
sign = -1.0;
t = sign / ((sign * l) + sqrtf(1.0 + l * l));
cs = 1.0 / sqrtf(1.0 + t * t);
sn = cs * t;
// Change columns i and j only
for (k = 0; k < row; k++) {
tmp = *(A + row*k + i);
*(A + row*k + i) = cs * tmp - sn * *(A + row*k + j);
*(A + row*k + j) = sn * tmp + cs * *(A + row*k + j);
}
// Update the right singular vectors
for (k = 0; k < row; k++) {
tmp = *(V + row*k + i);
*(V + row*k + i) = cs * tmp - sn * *(V + row*k + j);
*(V + row*k + j) = sn * tmp + cs * *(V + row*k + j);
}
}
}
}
// Find the singular values by adding up squares of each column, then taking square root of each column
for (j = 0; j < row; j++) {
for (i = 0; i < row; i++) {
*(S + j) += *(A + row*i + j) * *(A + row*i + j);
}
tmp = *(S + j);
*(S + j) = sqrtf(tmp);
}
// Sort the singular values largest to smallest, and the right matrix accordingly
for (p = 0; p < (row - 1); p++) {
for (j = 0; j < row - p - 1; j++) {
if (*(S + j) < *(S + j + 1)) {
tmp = *(S + j);
*(S + j) = *(S + j + 1);
*(S + j + 1) = tmp;
// Rearrange columns of u and v accordingly
for (i = 0; i < row; i++) {
tmp = *(V + row*i + j);
*(V + row*i + j) = *(V + row*i + j + 1);
*(V + row*i + j + 1) = tmp;
tmp = *(A + row*i + j);
*(A + row*i + j) = *(A + row*i + j + 1);
*(A + row*i + j + 1) = tmp;
}
}
}
}
// A is A*V, so in order to get U, we divide by S in each column
for (i = 0; i < row; i++) {
for (j = 0; j < row; j++) {
*(A + row*i + j) = *(A + row*i + j) / *(S + j);
}
}
// Set U to A, since we have been making modifications to A
memcpy(U, A, row*row*sizeof(float));
}
/*
* GNU Octave code:
* >> A
A =
3 4 5
2 5 6
5 6 7
>> [u, s, v] = svd(A)
u =
-0.47384 0.10757 -0.87402
-0.53340 -0.82478 0.18767
-0.70069 0.55512 0.44819
s =
Diagonal Matrix
14.91526 0 0
0 1.58310 0
0 0 0.16940
v =
-0.401719 0.915134 -0.033930
-0.587752 -0.229240 0.775885
-0.702260 -0.331630 -0.629962
>>
*/
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 5 mars 2020, 00:02:16
av Shimonu
Vad menar du skulle vara en minnesläcka? Du kör ju aldrig dynamisk allokering väl?
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 5 mars 2020, 00:02:41
av bearing
bearing skrev:Precis, resultatet blev ju exakt som jag skrev.
DanielM skrev:Vadå exakt som du skrev?
Jag kan ju inte kräva att du läser mina inlägg, men det hade ju varit roligare att skriva i dina trådar då. Får väl hoppa av den här också då.
DanielM skrev:Alltså jag menar att om jag har en for-loop som jag itererar +1 mer än vad en array har för element. Då borde väll jag få ett felmeddelande?
bearing skrev:
Mest sannolikt är att programmet bara börjar läsa/skriva nästa array i minnet.
DanielM skrev:Itererade en 4-array i en for-loop nu där loopen itererade 6 gånger. Inga felmeddelanden från IDE:n eller Valgrind.
Kod: Markera allt
b[0] = 0.091799
b[1] = 0.142268
b[2] = 0.229150
b[3] = 0.337254
b[4] = 0.649587 <- Från A
b[5] = 0.320520 <- Från A (A är alltså nästa array i minnet /bearing)
DanielM skrev:Alltså om jag har en array som rymmer 5 element och sedan initsaliserar jag den med 6 element.
Då varnar min IDE och markerar felet.
Men jag har aldrig fått någon varning om jag kör en funktion som har en for-loop i sig där for loppen skriver ut varje tal + ett extra element som inte finns.
bearing skrev:Vid kompileringen kan vissa fel upptäckas. Men inte under körning. Därför att den enda info som sparas om en array är dess placering i minnet. Längden på arrayen sparas inte.
Och om man ska gå in lite mer tekniskt, fungerar en array bara som en pekare. Den pekar på ett minnesutrymme som allokerats vid länkningen. Och pekaren är bara en variabel som innehåller ett nummer. Numret är adressen till starten på detta minnesutrymme.
Sen en kommentar angående "Valgrind". Jag har aldrig använt det programmet. Antog att det skulle fungera som liknande program, som går ut på att utföra "code coverage" samt att på andra sätt hitta buggar. Vet faktiskt inte om dessa program brukar identifiera att arrayer läses förbi max index. Men det har jag nog förutsatt när jag använt dem själv.
Med verifiering via Valgrind syftade jag på att du skulle kunna ta reda på ifall det vore möjligt att ställa in ett förväntat resultat. Typ när du kör algoritmen som hittar kortaste vägen. Då kan du hitta kortaste vägen via Octave eller för hand innan, och spara som ett förväntat resultat. Sen kan Valgrind (om det nu är kapabelt till detta) jämföra vad koden producerade, med vad som förväntades.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 5 mars 2020, 09:16:57
av DanielM
bearing skrev:
Jag kan ju inte kräva att du läser mina inlägg, men det hade ju varit roligare att skriva i dina trådar då. Får väl hoppa av den här också då.
Bättre om du kunde då förklara vad "det" betyder då.
bearing skrev:
Med verifiering via Valgrind syftade jag på att du skulle kunna ta reda på ifall det vore möjligt att ställa in ett förväntat resultat. Typ när du kör algoritmen som hittar kortaste vägen. Då kan du hitta kortaste vägen via Octave eller för hand innan, och spara som ett förväntat resultat. Sen kan Valgrind (om det nu är kapabelt till detta) jämföra vad koden producerade, med vad som förväntades.
Sådant gör jag redan. Skriver koden först i Octave och sedan konverterar jag den till octave. Det tar en tid att skriva från Octave till C.
Re: Maskinellt lärande i inbyggda system - Vem är på?
Postat: 5 mars 2020, 15:00:00
av Mr Andersson
Valgrind är primärt skapat för att hitta heap-fel. Stackanalyseringen är experimentell.
Om den hittar ett fel, bra då har du identifierat en bugg. Om den inte hittar några fel betyder det inte att koden är felfri.