I recently managed to build and run a simple CLAPACK Microsoft Visual Studio 2008 project (downloaded from http://icl.cs.utk.edu/lapack-for-windows/lapack/index.html). After that, inserting a single line after LAPACK dgesv_ call to initialize another integer tempInteger leads to the unsuccessful build. The error is: CLAPACK-EXAMPLE.c(30) : error C2143: syntax error : missing ';' before 'type'. It appears that execution of LAPACK function prevents certain actions such as variable initialization afterwards. Could anyone help me understand what's going on and fix it? Thanks in advance. The code listing is below:
#include < stdio.h>
#include "f2c.h"
#include "clapack.h"
int main(void)
{
/* 3x3 matrix A
* 76 25 11
* 27 89 51
* 18 60 32
*/
double A[9] = {76, 27, 18, 25, 89, 60, 11, 51, 32};
double b[3] = {10, 7, 43};
int N = 3;
int nrhs = 1;
int lda = 3;
int ipiv[3];
int ldb = 3;
int info;
int qqq = 1;
dgesv_(&N, &nrhs, A, &lda, ipiv, b, &ldb, &info);
if(info == 0) /* succeed */
printf("The solution is %lf %lf %lf\n", b[0], b[1], b[2]);
else
fprintf(stderr, "dgesv_ fails %d\n", info);
int tempInteger = 1;
return info;
}
If this file is compiled as C file and not C++ file then declaring tempInteger type should be done on th top of the function.
For example:
#include < stdio.h>
#include "f2c.h"
#include "clapack.h"
int main(void)
{
/* 3x3 matrix A
* 76 25 11
* 27 89 51
* 18 60 32
*/
double A[9] = {76, 27, 18, 25, 89, 60, 11, 51, 32};
double b[3] = {10, 7, 43};
int N = 3;
int nrhs = 1;
int lda = 3;
int ipiv[3];
int ldb = 3;
int info;
int qqq = 1;
int tempInteger;
dgesv_(&N, &nrhs, A, &lda, ipiv, b, &ldb, &info);
if(info == 0) /* succeed */
printf("The solution is %lf %lf %lf\n", b[0], b[1], b[2]);
else
fprintf(stderr, "dgesv_ fails %d\n", info);
tempInteger = 1;
return info;
}
Related
Well I posted this before but it's kinda improved now, and I only have one problem (I guess).
The assignment was to write a function which reads an integer matrix given in a ‘.txt file’ using
I/O redirection, then write another function to print it.
I read txt into a 1D array (arr) then create 2D matrix (mat) out of it, before those, I allocated memory dynamically bc our professor asked to do it that way. The problem is that arr seems to be changing when I put it on for loop and try to address it for the matrix. I would appreciate any ideas... Also, it would be helpful if you guys can comment on my way of allocating memory. (Don't forget we have 3 different input.txts some of them has -5.58234 like values or they are not seperated by "," in this example, so I want to make my code usable in any cases)
example txt file:
16, 11, 10, 16, 24, 40, 51, 61,
12, 12, 14, 19, 26, 58, 60, 55,
14, 13, 16, 24, 40, 57, 69, 56,
14, 17, 22, 29, 51, 87, 80, 62,
18, 22, 37, 56, 68, 109, 103, 77,
24, 35, 55, 64, 81, 104, 113, 92,
49, 64, 78, 87, 103, 121, 120, 101,
72, 92, 95, 98, 112, 100, 103, 99
my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int readMatrix(int *arr, int **mat);
void printMatrix(int **mat, int size);
int main(){
// declare 1D array and allocate memory
int *arr;
arr = malloc(sizeof(stdin)*sizeof(int));
// declare 2D Matrix and allocate memory
int **mat;
mat = (int **)malloc(sizeof(stdin)*sizeof(int));
// function implementations
int size;
size = readMatrix(arr, mat);
printMatrix(mat,size);
return 0;
}
int readMatrix(int *arr, int **mat){
// reading
int i=0, size=0; // loop var i and size to count the elements of array
while(scanf("%d,", &arr[i]) != EOF)
{
i++;
size++;
}
printf("arr[63] = %d \n\n",arr[63]); // VALUE IS CORRECT HERE
// finding row and column numbers
int rows = sqrt(size), cols = rows;
// appending 1d array into matrix
int m = 0;
// test printf("rows = %d, cols = %d\n", rows, cols);
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++){
printf("arr[%d] = %d\n",m, arr[m]); // VALUES OF arr[] BECAME WEIRD AFTER arr[12]
//mat[i][j] = arr[m]; // segmentation fault
//*(*(mat+i)+j) = arr[m]; // segmentation fault
//*(*(mat+i)+j) = &arr[m]; // segmentation fault
*(mat + i*cols + j) = &arr[m]; // I don't know if this is the proper way but it works
m++;
}
}
printf("\narr[63] = %d\n",arr[63]); // HOWWWWW
// return size for further implementations
//
return size;
}
void printMatrix(int **mat, int size){
int rows = sqrt(size), cols = rows;
printf("\nMATRIX A:\n");
for(int i=0; i<rows; i++){
for(int j=0; j<cols; j++)
{
printf("%d ", mat[i][j]);
//if(mat[i][j]>=10 && mat[i][j]<100 ){printf("%d ", mat[i][j]);}
//else if(mat[i][j]>=100 ){printf("%d ", mat[i][j]);}
//else{printf("%d ", mat[i][j]);}
}
printf("\n");
}
}
output:
$ ./secondtry < input1.txt
arr[63] = 99
arr[0] = 16
arr[1] = 11
arr[2] = 10
arr[3] = 16
arr[4] = 24
arr[5] = 40
arr[6] = 51
arr[7] = 61
arr[8] = 12
arr[9] = 12
arr[10] = 14
arr[11] = 19
arr[12] = 976
arr[13] = 8
arr[14] = 980
arr[15] = 8
arr[16] = 984
arr[17] = 8
arr[18] = 988
arr[19] = 8
arr[20] = 992
arr[21] = 8
arr[22] = 996
arr[23] = 8
arr[24] = 1000
arr[25] = 8
arr[26] = 1004
arr[27] = 8
arr[28] = 1008
arr[29] = 8
arr[30] = 1012
arr[31] = 8
arr[32] = 1016
arr[33] = 8
arr[34] = 1020
arr[35] = 8
arr[36] = 1024
arr[37] = 8
arr[38] = 1028
arr[39] = 8
arr[40] = 1032
arr[41] = 8
arr[42] = 1036
arr[43] = 8
arr[44] = 1040
arr[45] = 8
arr[46] = 1044
arr[47] = 8
arr[48] = 1048
arr[49] = 8
arr[50] = 1052
arr[51] = 8
arr[52] = 1056
arr[53] = 8
arr[54] = 1060
arr[55] = 8
arr[56] = 1064
arr[57] = 8
arr[58] = 1068
arr[59] = 8
arr[60] = 1072
arr[61] = 8
arr[62] = 1076
arr[63] = 8
arr[63] = 8
MATRIX A:
16 11 10 16 24 40 51 61
11 10 16 24 40 51 61 12
10 16 24 40 51 61 12 12
16 24 40 51 61 12 12 14
24 40 51 61 12 12 14 19
40 51 61 12 12 14 19 976
51 61 12 12 14 19 976 8
61 12 12 14 19 976 8 980
Because we're reading from stdin, we can not do simple things like:
read/parse the first to determine number of columns
rewind file
read/parse all lines and store in matrix (allocating space as we go)
Note that using sqrt on the count to get number of rows/columns is a bit "unique". This is the first time I've seen that done.
When handling a 2D matrix that has dynamic dimensions, it helps to define a control struct to be able to store the dimensions. Then, all relevant info for the matrix is available to everyone.
In general, I really prefer fgets/strtok/strtol over scanf.
In this use case, I'm not sure if scanf("%d,",&val) can parse both (e.g.) 103, and 99. That is, the last number of the input file has no comma after it.
So, I had to refactor the code quite a bit. It is annotated:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef DEBUG
#define dbgprt(_fmt...) \
printf(_fmt)
#else
#define dbgprt(_fmt...) \
do { } while (0)
#endif
// matrix control
typedef struct {
int mtx_cols; // number of columns
int mtx_rows; // number of rows (input lines)
int *mtx_base; // pointer to matrix data
} mtx_t;
// helper macro to access a given matrix coordinate
#define MTX(_mtx,_irow,_icol) \
_mtx->mtx_base[((_irow) * _mtx->mtx_cols) + _icol]
// newMatrix -- get new matrix control
mtx_t *
newMatrix(void)
{
mtx_t *mtx;
mtx = calloc(1,sizeof(*mtx));
return mtx;
}
// readMatrix -- read in matrix from stream
void
readMatrix(mtx_t *mtx,FILE *xfin)
{
char *bp;
char *cp;
char buf[1000];
// get first line as a special case to calculate the number of columns
fgets(buf,sizeof(buf),xfin);
// we need to preserve the original data for the second loop below
char tmp[1000];
strcpy(tmp,buf);
// calculate number of columns
bp = tmp;
while (1) {
char *cp = strtok(bp," ,\n");
bp = NULL;
if (cp == NULL)
break;
mtx->mtx_cols += 1;
}
// read in row by row
while (1) {
// get current row index and advance the row count
int irow = mtx->mtx_rows++;
dbgprt("BUF/%d: %s",irow,buf);
// add space for this row
mtx->mtx_base = realloc(mtx->mtx_base,
sizeof(*mtx->mtx_base) * mtx->mtx_rows * mtx->mtx_cols);
if (mtx->mtx_base == NULL) {
perror("realloc");
exit(2);
}
// parse this row
bp = buf;
for (int icol = 0; icol < mtx->mtx_cols; ++icol) {
char *cp = strtok(bp," ,\n");
bp = NULL;
if (cp == NULL)
break;
MTX(mtx,irow,icol) = strtol(cp,&cp,10);
dbgprt(" %d\n",MTX(mtx,irow,icol));
}
// get data for next row
if (fgets(buf,sizeof(buf),xfin) == NULL)
break;
}
}
void
printMatrix(const mtx_t *mtx)
{
printf("\nMATRIX A:\n");
for (int irow = 0; irow < mtx->mtx_rows; ++irow) {
for (int icol = 0; icol < mtx->mtx_cols; ++icol)
printf(" %d",MTX(mtx,irow,icol));
printf("\n");
}
}
int
main(int argc,char **argv)
{
--argc;
++argv;
FILE *xfin;
if (argc > 0)
xfin = fopen(*argv,"r");
else
xfin = stdin;
if (xfin == NULL)
exit(1);
// declare 1D array and allocate memory
mtx_t *mtx = newMatrix();
readMatrix(mtx,xfin);
printMatrix(mtx);
return 0;
}
We have two arrays A and B, each of 10 integers. Write a function that tests if every element of array A is equal to its corresponding element in array B. In other words, the function must check if A[0] is equal to B[0], A[1] is equal to B[1], and so forth. The function is to return true if all elements are equal and false if at least one element is not equal.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/* run this program using the console pauser or add
your own getch, system("pause") or input loop */
bool array(int ptr1[], int ptr2[]);
int main(int argc, char *argv[]) {
int array1[] = {11, 33, 34, 25, 16, 2, 24, 57, 86, 66};
int array2[] = {11, 33, 34, 25, 16, 2, 24, 57, 86, 66};
int i;
printf("Array A\t\tArray B\n");
for(i = 0; i < 10; i++)
printf("%d\t\t%d\n", array1[i], array2[i]);
printf("\nResult of comparision: \n");
bool result = array (array1, array2);
if(result == 1)
printf("false\n");
else
printf("false\n");
getch();
return 0;
}
The errors that I get are:
main.c(.text+0xfa): undefined 'array'
[Error] Id returned 1 exit status
recipe for target '"Problem' failed
The problem is you have declared array:
bool array(int ptr1[], int ptr2[]);
but not defined it. When you link, the linker looks for the definition of function array and cannot find one, prompting the error:
main.c(.text+0xfa): undefined 'array'
[Error] Id returned 1 exit status
recipe for target '"Problem' failed
To define the function at same point your declare it, you must add the body of the function. In that case, there is no need for a forward declaration. It has been declared before its use in main, e.g.
int arraycmp (int ptr1[], int ptr2[], size_t size)
{
return memcmp (ptr1, ptr2, size);
}
(note: regardless of whether you use memcmp or simply loop over each element and perform a single comparison for each, you must pass the number of elements as a parameter)
If on the other hand, you do not define the function until after main(), then the forward declaration is required so that the function is usable in main().
Putting it altogether, you can do something similar to the following:
#include <stdio.h>
#include <string.h>
/* run this program using the console pauser or add
your own getch, system("pause") or input loop */
int arraycmp (int ptr1[], int ptr2[], size_t size)
{
return memcmp (ptr1, ptr2, size);
}
int main (void) {
int array1[] = {11, 33, 34, 25, 16, 2, 24, 57, 86, 66},
array2[] = {11, 33, 34, 25, 16, 2, 24, 57, 86, 66},
i;
printf("Array A\t\tArray B\n");
for(i = 0; i < 10; i++)
printf(" %d\t\t %d\n", array1[i], array2[i]);
printf("\nResult of comparision: %s\n",
arraycmp (array1, array2, sizeof array1) ? "false" : "true");
#if defined (_WIN32) || defined (_WIN64)
getchar();
#endif
return 0;
}
(note: if there is any chance your arrays differ in number of elements, you should check before calling arraycmp and handle the error as you wish. Either return exiting that point or pass the size of the smaller and only compare that initial number of elements)
Example Use/Output
$ ./bin/arrcmp
Array A Array B
11 11
33 33
34 34
25 25
16 16
2 2
24 24
57 57
86 86
66 66
Result of comparision: true
Changing 57 to 56 in array2,
$ ./bin/arrcmp
Array A Array B
11 11
33 33
34 34
25 25
16 16
2 2
24 24
57 56
86 86
66 66
Result of comparision: false
Look things over and let me know if you have further questions.
I'm trying to read a file and store what it contains, but I'm getting segmentation fault, here is part of my code:
int nnodes;
int main(){
FILE * file = fopen("pub08.in", "r");
int nkeys;
fscanf(file, "%d %d", &nnodes, &nkeys);
long int graphsize = nnodes * nnodes;
long int * graph = malloc(graphsize * sizeof (long int));
for (int i = 0; i < graphsize; i++) {
graph[i] = IN;
}
for (int i = 0; i < nnodes; i++) {
long int a, b, prize;
fscanf(file, "%ld %ld %ld", &a, &b, &prize);
graph[a * nnodes + b] = prize;
graph[b * nnodes + a] = prize;
}
}
the file pub08.in looks like this:
100000 10000
61268 56095 10
40567 20917 17
97937 47973 13
74088 21826 13
62183 30464 11
97793 80708 12
35121 90180 10
77067 97297 17
4657 33995 16
88147 42709 18
95937 25936 19
79853 24452 11
9677 36288 11
91869 48767 15
34585 46478 17
41874 40622 15
13700 19942 18
15660 79277 14
...
Full file is here
The segmentation fault happens, I think, on line:
graph[a * nnodes + b] = prize;
What am I doing wrong?
Here is a list of things you are doing wrong:
Check the return values from fscanf.
Validate a and b to ensure that they are in range.
Check the return value from malloc
As per comment - check the return value from fopen
I need to solve the knapsack problem recursively, memoized and with dynamic programming. Currently I'm stuck at the dynamic programming method.
I adapted the code from what I found elsewhere on the internet. Currently the output is not correct.
The problem involves profit and mass. Each item has a profit and mass associated, there is a MAX_N (umber) of items available and a MAX_CAPACITY for mass. The aim is to have as much "profit" in the knapsack as possible.
Here is an example provided by the exercise:
Example: Given a knapsack of capacity 5, and items with mass[] = {2, 4, 3, 2}
and profit profit[] = {45, 40, 25, 15}, the best combination would be item 0 (with mass 2 and profit 45) and item 2 (with mass 3 and with profit 25) for a total profit of 70. No other combination with mass 5 or less has a greater profit.
Here is the complete code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_N 10
#define MAX_CAPACITY 165
int m[MAX_N][MAX_CAPACITY];
int max(int x, int y) {
return x ^ ((x ^ y) & -(x < y));
}
int min(int x, int y) {
return y ^ ((x ^ y) & -(x < y));
}
int knapsackRecursive(int capacity, int mass[], int profit[], int n) {
if (n < 0)
return 0;
if (mass[n] > capacity)
return knapsackRecursive(capacity, mass, profit, n-1);
else
return max(knapsackRecursive(capacity, mass, profit, n-1), knapsackRecursive(capacity - mass[n], mass, profit, n-1) + profit[n]);
}
int knapsackMemoized(int capacity, int mass[], int profit[], int n) {
}
int knapsackDynamic(int capacity, int mass[], int profit[], int n) {
int i;
int j;
for (i = 0; i <= n; i++) {
for (j = 0; j <= capacity; j++) {
if (i == 0 || j == 0)
m[i][j] = 0;
else if (mass[i-1] <= j)
m[i][j] = max(profit[i-1] + m[i-1][j-mass[i-1]], m[i-1][j]);
else
m[i][j] = m[i-1][j];
}
}
return m[n][capacity];
}
void test() {
// test values
//int M1[MAX_N] = {2, 4, 3, 2};
//int P1[MAX_N] = {45, 40, 25, 10};
int M1[MAX_N] = {6, 3, 2, 4};
int P1[MAX_N] = {50, 60, 40, 20};
int M2[MAX_N] = {23, 31, 29, 44, 53, 38, 63, 85, 89, 82};
int P2[MAX_N] = {92, 57, 49, 68, 60, 43, 67, 84, 87, 72};
// a)
printf("Recursion: %d\n",knapsackRecursive(MAX_CAPACITY, M1, P1, MAX_N));
printf("Recursion: %d\n",knapsackRecursive(MAX_CAPACITY, M2, P2, MAX_N));
printf("\n");
// b)
printf("Memoization: %d\n",knapsackMemoized(MAX_CAPACITY, M1, P1, MAX_N));
printf("Memoization: %d\n",knapsackMemoized(MAX_CAPACITY, M2, P2, MAX_N));
printf("\n");
// c)
printf("Dynamic Programming: %d\n",knapsackDynamic(MAX_CAPACITY, M1, P1, MAX_N));
printf("Dynamic Programming: %d\n",knapsackDynamic(MAX_CAPACITY, M2, P2, MAX_N));
}
int main() {
test();
}
This is the output I currently get. The recursive method should be supplying the correct result, but the dynamic programming one currently doesn't output the same. Memoization is not done yet, hence it doesn't output correctly either.
Recursion: 170
Recursion: 309
Memoization: 2686680
Memoization: 2686600
Dynamic Programming: 0
Dynamic Programming: 270
Process returned 25 (0x19) execution time : 0.269 s
Press any key to continue.
It turns out that the code I used for writing the dynamic programming part was supposed to work with int m[MAX_N+1][MAX_CAPACITY+1]; instead of int m[MAX_N][MAX_CAPACITY];.
Changing that has gotten me to a working code, if not really the code I wanted.
ok, here I have a small function that can sort some values written in the program
#include <stdio.h> /* printf */
#include <stdlib.h> /* qsort */
#include <conio.h> /* getch */
int values[] = { 40, 10, 100, 90, 20, 25 };
int compare (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
int main ()
{
int n;
qsort (values, 6, sizeof(int), compare);
for (n=0; n<6; n++)
printf ("%d ",values[n]);
getch();
}
this works perfectly, there are no errors given.
Now, in my main project, I have to sort values from file. I was thinking that I could copy these values over from file and do the exact same thing as here.
However, that might seem easy, but I also need their line in file, so that means I need a second array with the numbers 1-SIZE in it. Given that my file should max out at 512 lines. what steps can I take to make this work?
Example:
User ID: Score:
1 13
2 9
3 13
4 19
5 8
6 11
7 14
8 17
should be changed into
User ID: Score:
5 8
2 9
6 11
3 13
1 13
7 14
8 17
4 19
This is what you need
#include <stdio.h> /* printf */
#include <stdlib.h> /* qsort */
struct Element
{
int userId;
int score;
};
struct Element elements[] = {
{1, 13},
{2, 9},
{3, 13},
{4, 19},
{5, 8},
{6, 11},
{7, 14},
{8, 17},
};
int ascendingSortCompareFunction (const void * a, const void * b)
{
return (((struct Element *)a)->score - ((struct Element *)b)->score);
}
int descendingSortCompareFunction (const void * a, const void * b)
{
return ((struct Element *)b)->score) - (((struct Element *)a)->score;
}
int main ()
{
int n;
int count;
count = sizeof(elements) / sizeof(elements[0]);
qsort(elements, count, sizeof(elements[0]), ascendingSortCompareFunction);
printf ("UserID\tScore (Ascending Sort)\n");
for (n = 0 ; n < count ; n++)
printf ("%d\t%d\n", elements[n].userId, elements[n].score);
qsort(elements, count, sizeof(elements[0]), descendingSortCompareFunction);
printf ("UserID\tScore (Descending Sort)\n");
for (n = 0 ; n < count ; n++)
printf ("%d\t%d\n", elements[n].userId, elements[n].score);
getchar();
return 0;
}