Eigen::Map constructuctor complains about "Not a constant expression" - eigen3

Trying to instanciate a Map, I end up with the following compilation error message :
error: ‘iCol’ is not a constant expression
Map< Matrix < scomplex, iCol , iRow > > m;
src/tstEigen.cpp:161:40: error: ‘iCol’ is not a constant expression
Map< Matrix < scomplex, iCol , iRow > > m;
^
src/tstEigen.cpp:161:40: note: in template argument for type ‘int’
src/tstEigen.cpp:161:40: error: ‘iRow’ is not a constant expression
src/tstEigen.cpp:161:40: note: in template argument for type ‘int’
src/tstEigen.cpp:161:40: error: template argument 4 is invalid
src/tstEigen.cpp:161:40: error: template argument 5 is invalid
src/tstEigen.cpp:161:40: error: template argument 6 is invalid
src/tstEigen.cpp:161:42: error: template argument 1 is invalid
Map< Matrix < scomplex, iCol , iRow > > m;
Below the snippet :
void tst5( int iCol, int iRow)
{
Map< Matrix < scomplex, iCol , iRow > > m;
}
int main ()
{
tst5(4,2);
return 0;
}
May I ask you some hints please ?
Cheers
Sylvain

Sorry for the disturbance, I didn't use the proper sytax, here is the solution :
void tst5( int iCol, int iRow)
{
scomplex* pData = new scomplex[iCol * iRow];
Map< Matrix < scomplex, Dynamic, Dynamic > > m( pData, iCol , iRow);
}
Cheers

Related

Array type 'float [3]' is not assignable .Copying 2d Array in C

I have the following code below:
typedef struct
{
float K[6][3]; //Kalman gain ([row][column])
} FilterData;
void setFilterData(const FilterData *filterdata)
{
FilterData r;
int i;
int i1;
for (i = 0; i < 3; i++) {
for (i1 = 0; i1 < 6; i1++) {
r.K[i1 + 6 * i] = filterdata->K[i + 3 * i1];
}
}
}
Compiling this code leads to the following error:
setFilterData.c: In function setFilterData :
setFilterData.c:25:23: error: assignment to expression with array type
r.K[i1 + 6 * i] = filterdata->K[i + 3 * i1];
What is the alternative here?
Using memcpy explicitly also did not help.
FilterData r;
int i;
for (i = 0; i < 6; i++) {
memcpy(r.K + (3*i),filterdata->K + i,sizeof(float) );
memcpy(r.K + (3*i + 1),filterdata->K + (i+6),sizeof(float));
memcpy(r.K + (3*i + 2),filterdata->K + (i+12),sizeof(float));
}
Your problem is the FilterData.K is defined as a 2-dimensional array, but setFilterData() is treating it as if it were a 1-dimensional array.
The minimual fix is to say
r.K[i1][i] = filterData.K[i1][i]
(this assumes the transposition in your original code is a bug, not a feature, I'll have to read more about Kalman gain to know)
But there's no reason to double for-loop and assign each member separately. You could
memcpy(&r, filterData, sizeof(r))
or better yet
r = *filterData
r.K is a two-dimensional array. This means that r.K[n] is a float array of length 3. You can't assign a value to an array. For example, ask yourself what
int A[5];
A = 6;
would mean. If you want to assign a few to a specific location inside a two-dimensional (or multi-dimensional) array, you have to specify all of the indices.
for (i = 0; i < 3; i++) {
for (i1 = 0; i1 < 6; i1++) {
r.K[i1][i] = ... // I'm not sure what you actually want here.
}
}

C Functions homework build errors with passing arrays Help needed Beginner problems

I have been searching the net trying to resolve my build errors. I'm pretty sure once I fix these that my program will function but as I have yet been able to compile my code it makes it hard to test.
Any advice would be appreciated and yes this is homework. I'm new to C and I know I am probably making stupid mistakes. I will take all responses as a learning opportunity. The code is as follows. After the errors are posted.
// Program will take user input for student names and provide functions in
// order to sort by first name, by last name
// by score and a menu function.
#include <stdio.h>
#include <string.h>
// Prototypes for functions
int menu();
void searchLast(char [][21], char [][21],float [], int);
void searchFirst(char [][21], char [][21],float [], int);
void sortLast(char [][21], char [][21],float [], int);
void sortScore(char [][21], char [][21],float [], int);
void printRecords(char [][21], char [][21],float [], int);
int main()
{
int j,NumOfRecords, k = 0;
char FirstN[15][21],LastN[15][21];
float Score[15];
int select = 0;
// Asking for the number of records the students to add
printf("How many records would you like to enter, minimum of 5, max of 15? "); G
scanf("%d",&NumOfRecords);
for( k = 0; k < NumOfRecords; k++) // Loop to take user input and save in appropriate
// array location
{
for(j=0;j<21;j++)
{
scanf("First name: %s", &FirstN[k][j]);
scanf(" Last Name: %s", &LastN[k][j]);
scanf(" Score: %f", &Score[k]);
printf("\n");
}
}
select = menu(); // Calling menu function to assign selection to call the next function
printf("%d",select); // checking to see that selection was passed to 'select'
while (select != 0) // Sentinel loop to provide user with options to modify array output
{
if (select == 1) // prints all records
{
printRecords(FirstN,LastN,Score,NumOfRecords);
}
if (select == 2) //Searches for First name and prints associated records
{
searchFirst(FirstN,LastN,Score,NumOfRecords);
}
if (select == 3) // Searches for last name and prints associated records
{
searchLast(FirstN,LastN,Score,NumOfRecords);
}
if (select == 4) // Sorts records by score and prints associated records
{
sortScore(FirstN,LastN,Score,NumOfRecords);
}
if (select == 5) // Sorts by last name and prints associated records
{
sortLast(FirstN,LastN,Score,NumOfRecords);
}
if (select == 0) // Exits program
break;
select = menu();
}
return 0;
}
int menu() // The menu function
{
int num;
printf("Menu Options \n \n");
printf("Print Records (press 1) \n");
printf("Search by first name (press 2) \n");
printf("Search by last name (press 3) \n");
printf("Sort by score (press 4) \n");
printf("Sort by last name (press 5) \n");
printf("Exit the program (press 0) \n");
printf("Please enter option number: ");
scanf("%d", num); // Takes the selection to be passed out of the function
return num; // Returns the selection to main
}
void searchLast(char FirstName[][21],char LastName[][21], float Scores[],int NumOfRecords)
{
int j;
char Lname[1][21];
printf("Please enter last name to search for");
for (j=0;j<20;j++)
{
scanf("%s",Lname[0][j]);
}
for(j=0;j<NumOfRecords;j++)
{
if(Lname[0] == LastName[j])
{
printf("%s %s %f",FirstName[j],LastName[j],Scores[j]);
}
}
}
void searchFirst(char FirstName[][21],char LastName[][21], float Scores[],int NumOfRecords)
{
int j;
char Fname[1][21];
printf("Please enter last name to search for");
for (j=0;j<20;j++)
{
scanf("%s",Fname[0][j]);
}
for(j=0;j<NumOfRecords;j++)
{
if(Fname[0] == FirstName[j])
{
printf("%s %s %f",FirstName[j],LastName[j],Scores[j]);
}
}
}
void sortLast(char FirstName[][21],char LastName[][21], float Scores[],int NumOfRecords)
{
int j,x = 0;
int k;
for(j = 0; LastName[j] < LastName[j+1] ; j++)
{
for(k = (j+1) ; k < NumOfRecords; k++)
if (LastName[j] < LastName[k])
{
float temp = 0; // function attempts to sort Arrays saving string
char tempFirst; // values in a veriable to then be reassigned to
char tempLast; // appropriate Array index.
temp = Scores[j];
Scores[j] = Scores[k];
Scores[k] = temp;
tempLast = LastName[j];
LastName[j] = LastName[k];
LastName[k] = tempLast;
tempFirst = FirstName[j]
FirstName[j] = FirstName[k];
FirstName[k] = tempFirst;
}
void sortScore(char FirstName[15][21],char LastName[15][21], float Scores[],int NumOfRecords)
{
int j,x = 0;
int k;
for(j = 0; Scores[j] < Scores[j+1] ; j++)
{
for(k = (j+1) ; k < NumOfRecords; k++)
if (Scores[j] < Scores[k])
{
float temp = 0;
char tempFirst;
char tempLast;
temp = Scores[j];
Scores[j] = Scores[k];
Scores[k] = temp;
tempLast = LastName[j];
LastName[j] = LastName[k];
LastName[k] = tempLast;
tempFirst = FirstName[j]
FirstName[j] = FirstName[k];
FirstName[k] = tempFirst;
}
}
printRecords(FirstName,LastName,Scores,NumOfRecords);
}
void printRecords(char FirstName[][21],char LastName[][21], float Scores[],int NumOfRecords)
{
int j = 0;
for (j = 0; j < NumOfRecords ; j++)
{
printf("%s %s %f \n",FirstName[j],LastName[j],Scores[j]);
}
}
//Errors:
1>c:\[....]\meg4545.c(139): warning C4047: '=' : 'char' differs in levels of indirection from 'char *'
1>c:\[....]\meg4545.c(140): error C2106: '=' : left operand must be l-value
1>c:\[....]\meg4545.c(141): warning C4047: '=' : 'char [21]' differs in levels of indirection from 'char'
1>c:\[....]\meg4545.c(141): error C2106: '=' : left operand must be l-value
1>c:\[....]\meg4545.c(143): warning C4047: '=' : 'char' differs in levels of indirection from 'char *'
1>c:\[....]\meg4545.c(143): error C2146: syntax error : missing ';' before identifier 'FirstName'
1>c:\[....]\meg4545.c(143): error C2106: '=' : left operand must be l-value
1>c:\[....]\meg4545.c(144): warning C4047: '=' : 'char [21]' differs in levels of indirection from 'char'
1>c:\[....]\meg4545.c(144): error C2106: '=' : left operand must be l-value
1>c:\[....]\meg4545.c(146): error C2143: syntax error : missing ';' before 'type'
1>c:\[....]\meg4545.c(150): error C2143: syntax error : missing ';' before 'type'
1>c:\[....]\meg4545.c(162): warning C4047: '=' : 'char' differs in levels of indirection from 'char *'
1>c:\[....]\meg4545.c(163): error C2106: '=' : left operand must be l-value
1>c:\[....]\meg4545.c(164): warning C4047: '=' : 'char [21]' differs in levels of indirection from 'char'
1>c:\[....]\meg4545.c(164): error C2106: '=' : left operand must be l-value
1>c:\[....]\meg4545.c(166): warning C4047: '=' : 'char' differs in levels of indirection from 'char *'
1>c:\[....]\meg4545.c(166): error C2146: syntax error : missing ';' before identifier 'FirstName'
1>c:\[....]\meg4545.c(166): error C2106: '=' : left operand must be l-value
1>c:\[....]\meg4545.c(167): warning C4047: '=' : 'char [21]' differs in levels of indirection from 'char'
1>c:\[....]\meg4545.c(167): error C2106: '=' : left operand must be l-value
1>c:\[....]\meg4545.c(174): error C2143: syntax error : missing ';' before 'type'
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:02.31
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
One problem of probably many:
You have an array of char arrays (LastName[][21]) here:
void searchLast(char FirstName[][21],char LastName[][21], float Scores[],int NumOfRecords)
{
...
}
You're trying to copy char arrays here:
LastName[j] = LastName[k];
This is not how you copy strings in C. You must do something like this:
strncpy(LastName[j], LastName[k], 21);
EDIT
I forgot to mention: in C, char arrays become strings if they are NULL ('\0') terminated. You must pass strings to strncpy for it to work properly.

pointer to array assignment in C

I'm a having problem when trying to assign a pointer to array to another pointer to array, please could you tell me where is the problem in the code bellow :
void sort_strlen(char (*pt)[81]){
char (*temp)[81];
int i, j;
for(i = 0; i < 10 && *(pt + i) != NULL; i++)
for(j = i + 1; j < 10 && *(pt + j) != NULL; j++)
if(strlen(*(pt + i)) < strlen(*(pt + j))){
temp = *(pt + i);
*(pt + i) = *(pt + j);
*(pt + j) = temp;
}
for(i = 0; i < 10 && *(pt + i) != NULL; i++)
puts(*(pt + i));
}
GCC return "assigning incompatible types" error when compiling to this function. The problem must be obvious but I'm just a newbie, I can't find the problem by myself.
Is this the line that causes the error? Looks like it. (You should've indicated in your question.)
*(pt + j) = temp;
pt is of type char (*pt)[81] and temp is of the same type. But you dereference pt when you do *(pt + j). (* dereferences a pointer and instead refers to the variable the pointer points to.)
As a result, *(pt + j) is of type char[81]. And that's why it's an error to assign temp to it.
If you know what you're doing, you could get away with this by typecasting. But it appears this is not what you expect so I don't recommend that.
It may be easier to see the problem if we rewrite the function using subscript notation instead of *(pt+i).
void sort_strlen(char (*pt)[81]){
char (*temp)[81];
int i, j;
for(i = 0; i < 10 && pt[i] != NULL; i++)
for(j = i + 1; j < 10 && pt[j] != NULL; j++)
if(strlen(pt[i]) < strlen(pt[j])){
temp = pt[i];
pt[i] = pt[j];
pt[j] = temp;
}
for(i = 0; i < 10 && pt[i] != NULL; i++)
puts(pt[i]);
}
So when you're trying to swap pt[i] and pt[j], first you try to assign a char* (to which the char[81] pt[i] is automatically converted here) to a char(*)[81] in the temp = pt[i]; line.
The type incompatibility should be clear here. But usually, that one's only a warning and "works as intended" because pt[i] is converted to the address of the first byte in that string, which also is the address of the array pt[i]. The warning would vanish if the type of the right hand side is adjusted by assigning &pt[i] or pt + i.
The errors are on the next lines. In the pt[i] = pt[j]; line, you try to assign a char* to a char[81], and in the pt[j] = temp; line, you try to assign a char(*)[81] to a char[81].
Arrays are not assignable, so writing
pt[i] = ...
is always an error. It is unfortunate that gcc reports that as
sort_strlen.c:13:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char *’
sort_strlen.c:14:18: error: incompatible types when assigning to type ‘char[81]’ from type ‘char (*)[81]’
and not the more immediately pointing to the root cause
sort_strlen.c:13:18: error: array type 'char [81]' is not assignable
*(pt + i) = *(pt + j);
~~~~~~~~~ ^
sort_strlen.c:14:18: error: array type 'char [81]' is not assignable
*(pt + j) = temp;
~~~~~~~~~ ^
that clang emits. The "incompatible types" that gcc reports are principally unfixable since no type on the right hand side is compatible with an array type on the left hand side of an assignment.
I solved the problem by creating an array of pointers. I wanted to sort the strings directly by changing their addresses inside the array. Does anybody knows if it possible ? What is the best way to do it ?
That depends what you want to do. You can't change the addresses of the strings without moving the strings themselves around, you would do that for example with
char temp[81];
...
strcpy(temp, pt[i]);
strcpy(pt[i], pt[j]);
strcpy(pt[j], temp);
If you don't want to move the strings around, you would indeed best create an array of pointers
char *strings[10];
for(int i = 0; i < 10; ++i) {
strings[i] = pt[i]; // make it &pt[i][0] if you don't like the implicit conversion
}
and sort the strings array by string length:
char *temp;
...
if (strlen(strings[i]) < strlen(strings[j])) {
temp = strings[i];
strings[i] = strings[j];
strings[j] = temp;
}

Incompatible types in assignment - C

I'm trying to sort an array of strings, but my compiler keeps saying I have imcompatible types in my assignment.
Below is the code in question.
for(i = 0; i < 499; i++) {
max = 0;
for(j = 1; j < 500; j++) {
if(strncmp(user_id[max], user_id[j], 9) > 0) {
printf("max = %s, j = %s\n", user_id[max], user_id[j]);
temp = user_id[j];
user_id[j] = user_id[max];
user_id[max] = temp;
}
}
}
The following two lines throw the error:
user_id[j] = user_id[max];
user_id[max] = temp;
Why is it that I am receiving this error?
EDIT:
Sorry, I forgot to include this before.
char user_id[500][9];
char* temp;
i j and max are int.
rover-208-149:prog3 kubiej21$ gcc --ansi --pedantic -o prog3 prog3.c
prog3.c: In function ‘main’:
prog3.c:46: error: incompatible types in assignment
prog3.c:47: error: incompatible types in assignment
Arrays are not assignable in C. So the following is not valid:
char user_id[500][9];
user_id[23] = user_id[42]; // Error: trying to assign array
I'm not sure what you're trying to achieve, but perhaps memcpy is what you need?
memcpy(user_id[23], user_id[42], sizeof(user_id[23]));

Passing an 2-dimensional array to function and changing the values in it

I have a 2 dimensional array and i am passing it into a function and changing the values in the array
#define numRows 3
#define numCols 7
#define TotalNum (numRows*numCols)
int arr[numRows][numCols] = {{0,1,2,3,4,5,6}, {7,8,9,10,11,12,13},{14,15,16,17,18,19,20}};
1) random_rearrange_num(arr);
2) random_rearrange_num(arr);
void random_rearrange_num(int p[][numCols])
{
int temp = 0,k= 0,l = 0;
for(int i = numRows -1 ; i > 0 ; i--)
{
for (int j = numCols-1;j>0; j--)
{
k = 0 + rand()/(RAND_MAX/(2-0+1)+1);
l= 0 + rand()/(RAND_MAX/(6-0+1)+1);
temp = p[i][j];
p[i][j] = p[k][l];
p[k][l] = temp;
}
}
}
Basically, i am calling random_rearrange_num twice to randomly rearrange the numbers in the 2-d array.
But have some errors when i try to compile:
At point 1)
error C2440: 'initializing' : cannot convert from 'int [3][7]' to 'int'
At point 2)
error C2064: term does not evaluate to a function taking 1 arguments
Not sure what these errors are and how to correct them. Need some guidance on it...
I have only posted a bit of the code. The full code is here: https://codereview.stackexchange.com/questions/9419/programming-of-3-x-7-trick
In line 22 (int row = 0,), you should replace the comma by a semicolon. (Since you haven't a ;, the compiler thinks that the random_rearrange_num(arr) is an int declaration)
BTW, your code is c++. not c.
I think you should write a main() function to call random_rearrange_num().

Resources