freeBASIC Error?
-
- Posts: 27
- Joined: Jul 07, 2005 12:37
- Location: Malone, NY
- Contact:
freeBASIC Error?
The following program calculates the determinant of a matrix. In freeBASIC, the exe file crashes. I have -exx and -qb set. Could it be a stack overflow? I don't see a way to increase the stack size in FB. How would you do that?
DECLARE FUNCTION DET(a())
LET N=3
DIM a(N,N)
FOR r=1 TO N
FOR c=1 TO N
READ a(r,c)
NEXT c
NEXT r
DATA 4,5,-7,2,9,3,-6,12,5
PRINT DET(a())
SLEEP
END
'
' Calculate determinate using recursive
' expansion by minors.
'
FUNCTION DET(a())
LET n=UBOUND(a,1)
DIM m(n,n)
IF n = 2 THEN
LET d = a(1,1)*a(2,2) - a(2,1)*a(1,2)
ELSE
LET d = 0
FOR j1 = 1 TO n
' create minor
FOR i = 2 TO n
LET j2 = 1
FOR j = 1 TO n
IF j <> j1 THEN
LET m(i-1,j2) = a(i,j)
LET j2=j2+1
END IF
NEXT j
NEXT i
' calculate determinant
LET d = d + (-1.0)^(1 + j1)*a(1,j1)*DET(m())
NEXT j1
END IF
DET = d
END FUNCTION
DECLARE FUNCTION DET(a())
LET N=3
DIM a(N,N)
FOR r=1 TO N
FOR c=1 TO N
READ a(r,c)
NEXT c
NEXT r
DATA 4,5,-7,2,9,3,-6,12,5
PRINT DET(a())
SLEEP
END
'
' Calculate determinate using recursive
' expansion by minors.
'
FUNCTION DET(a())
LET n=UBOUND(a,1)
DIM m(n,n)
IF n = 2 THEN
LET d = a(1,1)*a(2,2) - a(2,1)*a(1,2)
ELSE
LET d = 0
FOR j1 = 1 TO n
' create minor
FOR i = 2 TO n
LET j2 = 1
FOR j = 1 TO n
IF j <> j1 THEN
LET m(i-1,j2) = a(i,j)
LET j2=j2+1
END IF
NEXT j
NEXT i
' calculate determinant
LET d = d + (-1.0)^(1 + j1)*a(1,j1)*DET(m())
NEXT j1
END IF
DET = d
END FUNCTION
-
- Posts: 360
- Joined: Jun 07, 2005 20:59
- Location: england, somewhere around the middle
- Contact:
Try the -t command line option, for future reference http://www.freebasic.net/wiki/wikka.php ... tPgCompOpt is the page to see for compiler options :)
Also, the forum has a feature to keep code separate from the rest of the text and make it easier on the eye, it's the Code button just under the subject box, click it once, paste your code and click it again.
Also, the forum has a feature to keep code separate from the rest of the text and make it easier on the eye, it's the Code button just under the subject box, click it once, paste your code and click it again.
-
- Posts: 2428
- Joined: Jul 19, 2006 19:17
- Location: Sunnyvale, CA
- Contact:
This is a stack overflow, but I think it means your program is not working right.
It looks to me like the Function is recursively called over 5,000 times before crashing (although I don't know what math you are attempting here). ;-)
Code: Select all
Dim Shared recursion
Declare Function DET(a())
Let N=3
Dim a(N,N)
For r=1 To N
For c=1 To N
Read a(r,c)
Next c
Next r
Data 4,5,-7,2,9,3,-6,12,5
Print DET(a())
Sleep
End
'
' Calculate determinate using recursive
' expansion by minors.
'
Function DET(a())
recursion += 1
Print recursion,
Let n=Ubound(a,1)
Dim m(n,n)
If n = 2 Then
Let d = a(1,1)*a(2,2) - a(2,1)*a(1,2)
Else
Let d = 0
For j1 = 1 To n
' create minor
For i = 2 To n
Let j2 = 1
For j = 1 To n
If j <> j1 Then
Let m(i-1,j2) = a(i,j)
Let j2=j2+1
End If
Next j
Next i
' calculate determinant
Let d = d + (-1.0)^(1 + j1)*a(1,j1)*DET(m())
Next j1
End If
DET = d
recursion -= 1
End Function
-
- Posts: 360
- Joined: Jun 07, 2005 20:59
- Location: england, somewhere around the middle
- Contact:
It seems like the arrays might have caught you with some bounds stuff, if
n = ubound(a()) - 1
and
for j1 = 0 to n (instead of 1 to n)
then I no longer get a segfault, however, testing it with what i think was the matrix
[1,4,7]
[2,5,8]
[3,6,9]
It gives me an answer of -3, whereas by hand I got 0, however, I'm not sure that I entered the matrix correctly and I could also naturally have made a mistake by hand, I'm not so great with the 3x3 matrices :)
Also, do you mind if I make this code work in -lang fb ?
edit: actually, that answer of -3 might be due to some bounds stuff, too, I've played a bit with your code before I got it working, but basically if you adjust your algorithm so that a() is assumed to go from a(0,0) and the upper bound being ubound-1 (i think) then it will work (i think)
also, I notice you allow unsquare matrices, are the determinants of these defined?
n = ubound(a()) - 1
and
for j1 = 0 to n (instead of 1 to n)
then I no longer get a segfault, however, testing it with what i think was the matrix
[1,4,7]
[2,5,8]
[3,6,9]
It gives me an answer of -3, whereas by hand I got 0, however, I'm not sure that I entered the matrix correctly and I could also naturally have made a mistake by hand, I'm not so great with the 3x3 matrices :)
Also, do you mind if I make this code work in -lang fb ?
edit: actually, that answer of -3 might be due to some bounds stuff, too, I've played a bit with your code before I got it working, but basically if you adjust your algorithm so that a() is assumed to go from a(0,0) and the upper bound being ubound-1 (i think) then it will work (i think)
also, I notice you allow unsquare matrices, are the determinants of these defined?
After translating the C source from here, for the specified matrix I get 370, in only 3 recursions. I’m not sure that the code is right and I did not attempt to check the 370 manually.
When I do stuff like this I can’t help but think how strange it is that some people complain about the C features that have been incorporated into FreeBASIC.
Code: Select all
'================================================================================
dim shared as integer rcnt
function Determinant( byval a as double ptr ptr, byval n as integer ) as double
dim as integer i,j,j1,j2 '' general loop and matrix subscripts
dim as double det '' init determinant
dim as double ptr ptr m '' pointer to pointers to implement 2d
'' square array
rcnt += 1
if n < 1 then '' error condition, should never get here
print "error"
elseif n = 1 then
det = a[0][0] '' should not get here
elseif n = 2 then '' basic 2X2 sub-matrix determinate
'' definition. When n==2, this ends the
'' recursion series
det = a[0][0] * a[1][1] - a[1][0] * a[0][1]
else '' recursion continues, solve next sub-
'' matrix
'' solve the next minor by building a
'' sub matrix
det = 0 '' initialize determinant of sub-matrix
for j1 = 0 to n-1 '' for each column in sub-matrix
m = callocate((n-1)*sizeof(double ptr)) '' get space for the pointer list
for i = 0 to n-2
m[i] = callocate((n-1)* sizeof(double))
'' i[0][1][2][3] first malloc
'' m -> + + + + space for 4 pointers
'' | | | | j second malloc
'' | | | +-> _ _ _ [0] pointers to
'' | | +----> _ _ _ [1] and memory for
'' | +-------> _ a _ [2] 4 doubles
'' +----------> _ _ _ [3]
''
'' a[1][2]
'' build sub-matrix with minor elements excluded
next i
for i = 1 to n-1
j2 = 0 '' start at first sum-matrix column
'' position
for j = 0 to n-1 '' loop to copy source matrix less
'' one column
if j = j1 then continue for '' don't copy the minor column element
m[i-1][j2] = a[i][j] '' copy source element into new sub-
'' matrix
'' i-1 because new sub-matrix is one
'' row (and column) smaller with
'' excluded minors
j2+=1 '' move to next sub-matrix column
'' position
next j
next i
'' sum x raised to y power
'' recursively get determinant of
'' next sub-matrix which is now one
'' row & column smaller
det += -1.0 ^ (1.0 + j1 + 1.0) * a[0][j1] * Determinant(m,n-1)
for i = 0 to n-2
deallocate m[i] '' free the storage allocated to
'' to this minor's set of pointers
next i
deallocate m '' free the storage for the original
'' pointer to pointer
next j1
end if
return det
end function
'' Start of implicit main.
dim as integer n = 3
dim as double ptr p(0 to n-1)
dim as double a(0 to n-1,0 to n-1)
for r as integer = 0 to n-1
for c as integer = 0 to n-1
read a(r,c)
next
next
for i as integer = 0 to n-1
p(i) = @a(i,0)
next
print Determinant(@p(0),n)
print rcnt
sleep
end
data 4,5,-7,2,9,3,-6,12,5
-
- Posts: 27
- Joined: Jul 07, 2005 12:37
- Location: Malone, NY
- Contact:
FB Bug?
Thanks for all the helpful replies! The problem *was* a stack overflow. I added -t 5000 to compiler options and an OPTION BASE 1 to the beginning of the program. I would have thought -exx would have caught the stack error. The answer to the matrix as given is 0 which was an unfortunate result since that could also be the result of a faulty program. If you change the first number from 1 to 12,
like so:
[12,4,7]
[2,5,8]
[3,6,9]
the answer is -33 which is correct.
As for the C examples: That's exactly why I don't like C. All that referencing and dereferencing and getting space for pointers, etc. You have to think more about how the computer works than concentrating on the problem to be solved!
like so:
[12,4,7]
[2,5,8]
[3,6,9]
the answer is -33 which is correct.
As for the C examples: That's exactly why I don't like C. All that referencing and dereferencing and getting space for pointers, etc. You have to think more about how the computer works than concentrating on the problem to be solved!
He's probably trying to find a solution to a series of equations.KristopherWindsor wrote:This is a stack overflow, but I think it means your program is not working right.
It looks to me like the Function is recursively called over 5,000 times before crashing (although I don't know what math you are attempting here). ;-)Code: Select all
Dim Shared recursion Declare Function DET(a()) Let N=3 Dim a(N,N) For r=1 To N For c=1 To N Read a(r,c) Next c Next r Data 4,5,-7,2,9,3,-6,12,5 Print DET(a()) Sleep End ' ' Calculate determinate using recursive ' expansion by minors. ' Function DET(a()) recursion += 1 Print recursion, Let n=Ubound(a,1) Dim m(n,n) If n = 2 Then Let d = a(1,1)*a(2,2) - a(2,1)*a(1,2) Else Let d = 0 For j1 = 1 To n ' create minor For i = 2 To n Let j2 = 1 For j = 1 To n If j <> j1 Then Let m(i-1,j2) = a(i,j) Let j2=j2+1 End If Next j Next i ' calculate determinant Let d = d + (-1.0)^(1 + j1)*a(1,j1)*DET(m()) Next j1 End If DET = d recursion -= 1 End Function
IE:
Code: Select all
x = Dx/D
y = Dy/D
z = Dz/D
Doing this using the Gauss Jordan Row reduction method is a bit messy to code. Trust me I coded a row reduction solver and coding it sucked.
Code: Select all
#include <stdio.h>
#include <conio.h>
#include <math.h>
int main(void)
{
//table for storing coeeficients
//matrix[row][col]
float matrix[3][4];
//declare variables
int row, col;
float rowmul,rowadd,eadd,recip;
clrscr();
//temporary value storage
float input=0;
//first eq
puts("enter coeeficients for 1st eq ax + by + cz = d:");
printf("a ");scanf("%f", &input); //get value from keyboard
matrix[0][0] = input; //set table
printf("b ");scanf("%f", &input);
matrix[0][1] = input;
printf("c ");scanf("%f", &input);
matrix[0][2] = input;
printf("d ");scanf("%f", &input);
matrix[0][3] = input;
//row 2
puts("enter coeeficients for 2nd eq ax + by + cz = d:");
printf("a ");scanf("%f", &input);
matrix[1][0] = input;
printf("b ");scanf("%f", &input);
matrix[1][1] = input;
printf("c ");scanf("%f", &input);
matrix[1][2] = input;
printf("d ");scanf("%f", &input);
matrix[1][3] = input;
//row3
puts("enter coeeficients for 3rd eq ax + by + cz = d:");
printf("a ");scanf("%f", &input);
matrix[2][0] = input;
printf("b ");scanf("%f", &input);
matrix[2][1] = input;
printf("c ");scanf("%f", &input);
matrix[2][2] = input;
printf("d ");scanf("%f", &input);
matrix[2][3] = input;
//print original matrix
printf( "\n");
printf( "Original matrix \n");
for (row = 0; row < 3; row++)
{
for (col = 0; col <4; col++)
{
printf( " %8.0f",matrix[row][col]);
}
printf( " \n");
}
//suspend until enter is pressed
getchar();
getchar();
//clear screen for output
clrscr();
//print the coeff in equation form
printf( "\n");
printf( "3 variable linear equation: \n");
for (row = 0; row < 3; row++)
{
printf( "%2.0fx + %2.0fy + %2.0fz = %2.0f ",matrix[row][0],matrix[row][1]
,matrix[row][2],matrix[row][3]);
printf( " \n");
}
//print augmented matrix
printf( "\n");
printf( "augmented matrix: \n");
for (row = 0; row < 3; row++)
{
for (col = 0; col <4; col++)
{
printf( " %8.0f",matrix[row][col]);
}
printf( " \n");
}
//gaussian row - reduction algo
//eliminate all first element
//of all rows except first row
for (row=0; row<2; ++row)
{
rowadd = -matrix[row + 1][ 0];
for (col = 0; col <4; ++col)
{
eadd = rowadd * matrix[0][col];
matrix[row+1][col] += eadd;
}
}
int colcount = 0; //what column are we in now?
for (row = 0; row<2; ++row)
{
//set current row and current column to 1
// by multiplying by its inverse
//checking for divide by zero error
if (matrix[row][colcount] != 0)
rowmul = (float)1.0/matrix[row][colcount];
else
rowmul = 0;
//multiply all the column by the reciprocal
for (col=0; col<4; ++col)
matrix[row][col] *= rowmul;
//eliminate current row, current col(set to zero)
//by adding its inverse
rowadd = -matrix[row+1][colcount];
for (col=0; col<4; ++col)
{
eadd = rowadd * matrix[row][col];
matrix[row+1][col] += eadd;
}
//set next row, next col to 1 by multiplying by
//reciprocal
//also check for zero divisor
if (matrix[row+1][colcount+1] != 0)
recip = (float)1.0/matrix[row+1][colcount+1];
else
recip = 0;
for (col=0; col<4; ++col)
matrix[row+1][col] *= recip;
//increment column counter
colcount++;
}
//print the processed matrix
printf( "\n");
printf( "Triangular matrix: \n");
for (row=0; row<3; row++)
{
for (col = 0; col < 4; col++)
printf(" %8.0f", matrix[row][col]);
printf("\n");
}
//calculate and print solutions
float x, y, z;
z = matrix[2][3];
y = matrix[1][3] + -(matrix[1][2]*z);
x = matrix[0][3]+ -(matrix[0][1]*y)+ -(matrix[0][2]*z);
printf("\n");
printf("Solution: \n");
printf( "x = %2.0f \n", x);
printf( "y = %2.0f \n", y);
printf( "z = %2.0f \n", z);
printf("\n");
printf("Press enter to exit...");
getchar();
getchar();
getchar();
return 0;
} //end main
For the code from the first post, compiled with v18.2b for Windows and -lang qb and -t 5000, with an option base 1 statement and using:
data 12,4,7,2,5,8,3,6,9
Dr Watson is still showing:
Exception number: c00000fd (stack overflow)
data 12,4,7,2,5,8,3,6,9
Dr Watson is still showing:
Exception number: c00000fd (stack overflow)
Code: Select all
'====================================================================
option base 1
'====================================================================
'' This will work, but only for 3x3.
function D3()
dim as integer a1,b1,c1,a2,b2,c2,a3,b3,c3
read a1
read b1
read c1
read a2
read b2
read c2
read a3
read b3
read c3
D3 = a1*b2*c3+b1*c2*a3+c1*a2*b3-a3*b2*c1-b3*c2*a1-c3*a2*b1
end function
'====================================================================
' Calculate determinate using recursive
' expansion by minors.
'
FUNCTION DET(a())
LET n=UBOUND(a,1)
DIM m(n,n)
IF n = 2 THEN
LET d = a(1,1)*a(2,2) - a(2,1)*a(1,2)
ELSE
LET d = 0
FOR j1 = 1 TO n
' create minor
FOR i = 2 TO n
LET j2 = 1
FOR j = 1 TO n
IF j <> j1 THEN
LET m(i-1,j2) = a(i,j)
LET j2=j2+1
END IF
NEXT j
NEXT i
' calculate determinant
LET d = d + (-1.0)^(1 + j1)*a(1,j1)*DET(m())
NEXT j1
END IF
DET = d
END FUNCTION
'====================================================================
'' Start of implicit main.
print D3()
print
sleep
LET N=3
DIM a(N,N)
FOR r=1 TO N
FOR c=1 TO N
READ a(r,c)
NEXT c
NEXT r
PRINT DET(a()), r
sleep
end
'data 4,5,-7,2,9,3,-6,12,5
'data 4,5,-7,2,9,3,-6,12,5
data 12,4,7,2,5,8,3,6,9
data 12,4,7,2,5,8,3,6,9