Initialize an "eye" (identity) matrix array in C - c

int eye[3][3] = {
{ 1,0,0 },
{ 0,1,0 },
{ 0,0,1 }
};
Is there a shorter way to initialize it? It's so regular that there must be a smarter way to initialize it, especially if it's more than 3x3, say 10x10 or more.

In c99 you can write:
int eye[][3] = { [0][0] = 1, [1][1] = 1, [2][2] = 1 };
all other elements are zeroed, moreover the compiler figures out the size of the array for you. Just don't skip the second size (3).
Btw. in your code you don't have to use the double braces, this would be fine too:
int eye[3][3] = {
1,0,0,
0,1,0,
1,0,1,
};
In c99 you can also leave the trailing comma, just for symmetry and future refactorings
Other solutions probably require you to write some code, which may indeed save you some time/space in file. But note that this way you're splitting declaration and "initialization", which in case of e.g. globals can make a difference.

You can use designated initializers:
int eye[3][3] = { [0][0]=1, [1][1]=1, [2][2]=1};
All the other elements will be initialized to 0 as per C standard's guarantee.

You may try the following:
#define SIZE 3
int eye[SIZE][SIZE] = {0};
for (int i = 0; i < SIZE ; ++i)
{
eye[i][i] = 1;
}

If you want to store {{ 1,0,0 }, { 0,1,0 }, ...} this style of values in square matrix means, you can write a simple logic as below.
#define SIZE 3
int eye[SIZE][SIZE] = {0};
int *p = (int *)eye;
for (i = 0; i < (SIZE * SIZE); i = i + (SIZE + 1))
{
p[i] = 1;
}
or
for (i = 0; i < SIZE; i++)
{
for (j = 0; j < SIZE; j++)
{
if (i == j)
{
eye[i][j] = 1;
}
else
{
eye[i][j] = 0;
}
}
}
Note : Above logic is only for the sample value you have given. So try to find similar logic if your values are having some relation. If not so, then no other way to initialize it directly even if size of matrix is 1000x1000.

Related

passing a pointer to a structure as a parameter

I have a structure that I've set up, and a pointer to the structure, that is basically an array. I want to create a function that modifies specific values within the structure but can't seem to figure out how to pass in the structure pointer as a parameter.
struct deviations {
int switch;
int x;
int y;
};
struct deviations *pdevs = malloc(24 * sizeof(int));
for(int i = 0; i < 8; i++) {
(pdevs + i)->switchez = 1;
(pdevs + i)->x = 0;
(pdevs + i)->y = 0;
}
int top[3] = {0, 1, 2};
int bottom[3] = {5, 6, 7};
int left[3] = {0, 3 ,5};
int right[3] = {2, 4, 7};
for(int i = 0; i < 3; i++) {
(pdevs + top[i])->y = -1;
}
I have multiple (8) for loops like above and in each of them the basic structure is the same, except the array ("top"), lvalue ('y') and rvalue ('-1') change in each. I can't figure out how to declare a function with the structure/pointer to structure properly.
I currently have it around 26 lines of (8 for loops repeating) code and am pretty sure I can compress it down to a tidy little function if I can figure out how to pass in the pointer to the structure. Any help would be much appreciated!
This snippet is part of a larger function/program that determines whether or not to check the surrounding items (3 up top, 3 at bottom, one on each side). I have set up a structure with an on/off switch based on the position of the base item, and an x/y offset. I am trying to shift each individual cell by a certain amount +1/-1/ or 0 in the x or y position. And I am trying to flip the switch on or off depending on certain conditions about the x or y of the original cell. Malloc is probably unnecessary, but am unsure whether or not this array of structs will be used again later, if not, I will remove the call to malloc.
Thanks!
So you want a generic function that can take an array of 3 indexes, the structure member to fill in, and the value.
The array and value are simple. To handle a structure member generically, you can use the offsetof() macro.
void fill_structs(struct deviations *pdevs, size_t offset, int indexes[3], int value) {
for (int i = 0; i < 3; i++) {
*((int *)((char *)&pdevs[indexes[i]] + offset)) = value;
}
}
Then you call it like:
fill_structs(pdevs, offsetof(struct deviations, y), top, -1);
offsetof() returns the offset in bytes of a structure member from the base of the structure. So in the function you have to convert the address of the array element to char * so you can add the offset to it, then convert it to int * so you can dereference it and assign to the int member there.
BTW, you should get out of the habit of using things like
(pdevs + i) -> x
If you're using a pointer as the base of an array, use array syntax:
pdevs[i].x
It's much easier to tell that i is an array index this way.
This answer serves purely to challenge your thinking about your current approach.
Personally, unless there's some special logic involved, I would just ditch the loops completely and initialize your struct like this.
const struct deviations devs[8] = {
{ 1, -1, -1 }, // top-left
{ 1, 0, -1 }, // top
{ 1, 1, -1 }, // top-right
{ 1, -1, 0 }, // left
{ 1, 1, 0 }, // right
{ 1, -1, 1 }, // bottom-left
{ 1, 0, 1 }, // bottom
{ 1, 1, 1 } // bottom-right
};
If you then decide that you really need to allocate that dynamically then you could just copy it:
struct deviations *pdevs = malloc(sizeof(devs));
if (pdevs) memcpy(pdevs, devs, sizeof(devs));
But if you really wanted to generate this stuff in a loop, why not something like this?
int ii = 0;
for(int y = -1; y <= 1; ++y) {
for(int x = -1; x <= 1; ++x) {
if (x == 0 && y == 0) continue;
pdevs[ii].switch = 1;
pdevs[ii].x = x;
pdevs[ii].y = y;
++ii;
}
}

Counting and removing duplicates in an array c

Let's say I have an array with [2,4,6,7, 7, 4,4]
I want a program that can iterate through, and then print out something like this:
Value: Count:
2 1
4 3
6 1
7 2
I don't want it to print out ex 4 three times.
What I got so far:
for (int i = 0; i < numberOfInts; i++)
{
dub[i] = 0;
for (int y = 0; y < numberOfInts; y++)
{
if (enarray[i] == enarray[y])
{
dub[i]++;
}
}
}
So basically I check each element in the array against all the elements, and for every duplicate I add one to the index in the new array dub[].
So if I ran this code with the example array above, and then printed it out with I'd get something like this:
1,3,1,2,2,3,3. These are pretty confusing numbers, because I don't really know which numbers these belong to. Especially when I'll randomize the numbers in the array. And then I have to remove numbers so I only have one of each. Anyone got a better solution?
You can iterate through the array while checking for each element if it has been repeated in which case you increment it's count (the loop checks only values a head saving processing time). This let you accomplish what you needed without creating any extra buffer array or structure.
The bool 'bl' prevents repeated printing
int main() {
int arr[] = { 2, 4, 6, 7, 7, 4, 4 };
int size = (sizeof(arr) / sizeof(int));
printf("Value:\tCount\n");
for (int i = 0; i < size; i++) {
int count = 0, bl = 1; //or 'true' for print
//check elements ahead and increment count if repeated value is found
for (int j = i; j < size; j++) {
if (arr[i] == arr[j]) {
count++;
}
}
//check if it has been printed already
for (int j = i-1; j >= 0; j--) {
if (arr[i] == arr[j]) {
bl = 0; //print 'false'
}
}
if (bl) { printf("%d\t\t%d\n", arr[i], count); }
}
return 0;
}
Given the char array only contains '0' to '9', you may utilize a trivial lookup table like this:
#include <stdio.h>
typedef struct
{
char c;
int num;
} TSet;
TSet my_set[] =
{
{ '0', 0 },
{ '1', 0 },
{ '2', 0 },
{ '3', 0 },
{ '4', 0 },
{ '5', 0 },
{ '6', 0 },
{ '7', 0 },
{ '8', 0 },
{ '9', 0 },
};
int main()
{
char a[] = {'2','4','6','7','7', '4','4'};
int i;
for( i = 0; i < sizeof(a) / sizeof(char); i++ )
{
my_set[ a[i] - '0' ].num++;
}
printf( "%-10s%-10s\n", "Value:", "Count:" );
for( i = 0; i < sizeof(my_set) / sizeof(TSet); i++ )
{
if( my_set[i].num != 0 )
{
printf( "%-10c%-10d\n", my_set[i].c, my_set[i].num );
}
}
}
Output:
Value: Count:
2 1
4 3
6 1
7 2
I don't understand the complexity here. I think there are two approaches that are performant and easy to implement:
Counting Sort
requires int array of size of the biggest element in your array
overall complexity O(n + m) where m is the biggest element in your array
qsort and enumeration
qsort works in O(n * log(n)) and gives you a sorted array
once the array is sorted, you can simply iterate over it and count
overall complexity O(n*log(n))
sort the array, typically by using the qsort() function
iterate over all elements counting successively equal elements and if the next different element is detected print the count of the former
This works on any number of different elements. Also no second array is needed.
You have the general idea. In addition to your input array, I would suggest three more arrays:
a used array that keeps track of which entries in the input have already been counted.
a value array that keeps track of the distinct numbers in the input array.
a count array that keeps track of how many times a number appears.
For example, after processing the 2 and the 4 in the input array, the array contents would be
input[] = { 2,4,6,7,7,4,4 };
used[] = { 1,1,0,0,0,1,1 }; // all of the 2's and 4's have been used
value[] = { 2,4 }; // unique numbers found so far are 2 and 4
count[] = { 1,3 }; // one '2' and three '4's
Put a print statement in the outer for loop to print value and repetition
for (int i = 0; i < numberOfInts; i++)
{
dub[i] = 0;
for (int y = 0; y < numberOfInts; y++)
{
if (enarray[i] == enarray[y])
{
dub[i]++;
}
}
printf("%d%d",enarray[i], dub[i]);
}
What you're asking for is strange. Normally, I'd create a struct with 2 members, like 'number' and 'count'. But let's try exactly what you're asking for (unidimensional array with each number followed by it's count):
int
i,
numberOfInts = 7,
numberOfDubs = 0,
enarray[7] = {2,4,6,7,7,4,4},
dub[14]; // sizeof(enrray) * 2 => maximum number of dubs (if there are no duplicates)
// For every number on enarray
for(i = 0; i < numberOfInts; i++)
{
int jump = 0;
// Check if we have already counted it
// Only check against pairs: Odds are the dub counter
for(int d = 0; d < numberOfDubs && !jump; d += 2)
{
if(dub[d] == enarray[i])
{
jump = 1;
}
}
// If not found, count it
if(!jump)
{
// Assign the new number
dub[numberOfDubs] = enarray[i];
dub[numberOfDubs + 1] = 1;
// We can begin from 'i + 1'
for(int y = i + 1; y < numberOfInts; y++)
{
if(enarray[i] == enarray[y])
{
dub[numberOfDubs + 1]++;
}
}
// Increment dub's counter by 2: number and it's counter
numberOfDubs += 2;
}
}
// Show results
for(i = 0; i < numberOfDubs; i += 2)
{
printf("%d repeated %d time%s\n", dub[i], dub[i + 1], (dub[i + 1] == 1 ? "" : "s"));
}

MQL4 array creating variables

I'm trying to make this function create X number of variables using an array. I know that this is technically wrong because I need a constant as my array's value (currently 'x'), but excluding that, what am I missing? Looked at so many code samples and can't figure it out, but I know it's got to be simple...
void variables()
{
int i;
int bars = 10;
int x = 1;
for (i = 1; i <= bars+1; i++)
{
int variables[bars] = { x };
x++;
if (i >= bars+1)
{
break;
}
}
void variables()
{
int bars = 10;
if(bars >= Bars) bars = Bars - 1;
// to be able to set array size based on variable,
// make a dynamically sized array
double highvalues[];
ArrayResize(highvalues, bars);
for (int i = 0 /*Note: Array index is zero-based, 0 is first*/; i <= bars; i++)
{
highvalues[i] = iHigh(NULL, 0, i);
// or
highvalues[i] = High[i];
}
}
It is hard to tell what do you want to achieve.
If you want to fill an array with a value ArrayFill() fill help you.

Function Warnings in C

Hello guys i have threefunctions for which i get 4 warnings...!!
The first one is this
void evaluatearxikos(void)
{
int mem;
int i;
double x[NVARS+1];
FILE *controlpointsarxika;
controlpointsarxika = fopen("controlpointsarxika.txt","r");
remove("save.txt");
for(mem = 0; mem < POPSIZE; mem++)
{
for(i = 0; i < NVARS; i++)
{
x[i+1] = population[mem].gene[i];
}
rbsplinearxiki();
XfoilCall();
population[mem].fitness = FileRead();
remove("save.txt");
}
fclose(controlpointsarxika);
}
For this one the compiler warns me tha variable x is set but not used...!! But actually i am using the variable x...!!!
The second function is this one...
void elitist(void)
{
int i;
double best,worst;
int best_mem,worst_mem;
best = population[0].fitness;
worst = population[0].fitness;
for(i = 0; i < POPSIZE - 1; i++)
{
if(population[i].fitness > population[i+1].fitness)
{
if(population[i].fitness >= best)
{
best = population[i].fitness;
best_mem = i;
}
if(population[i+1].fitness <= worst)
{
worst = population[i+1].fitness;
worst_mem = i+1;
}
}
else
{
if(population[i].fitness <= worst)
{
worst = population[i].fitness;
worst_mem = i;
}
if(population[i+1].fitness >= best)
{
best = population[i+1].fitness;
best_mem = i+1;
}
}
}
if(best >= population[POPSIZE].fitness)
{
for(i = 0; i < NVARS; i++)
{
population[POPSIZE].gene[i] = population[best_mem].gene[i];
}
population[POPSIZE].fitness = population[best_mem].fitness;
}
else
{
for(i = 0; i < NVARS; i++)
{
population[worst_mem].gene[i] = population[POPSIZE].gene[i];
}
population[worst_mem].fitness = population[POPSIZE].fitness;
}
}
For this one i get two warnings that the variables worst_mem and best_mem may be used uninitialized in this function..!! But i initialize values to both of them..!!
And the third function is this...
void crossover(void)
{
int mem,one;
int first = 0;
double x;
for(mem =0; mem < POPSIZE; mem++)
{
x = rand()%1000/1000;
if(x < PXOVER)
{
first++;
if(first%2 == 0)
{
random_Xover(one,mem);
}
else
{
one = mem;
}
}
}
}
For which i get that the variable one may be used unitialized..!! But it is initialized..!
Can you please tell me what is wrong with these functions...??
Thank you in advance
In your first function, you set (assign) x, but you never read it, hence you are not using it... you're only wasting CPU cycles by writing to it. (Note also that because you index it as i+1 you write beyond the space you've allocated for it).
In the second function, your initializations to those variables are in conditional blocks. You can see that (perhaps? I didn't verify) in all conditions they are initialized but your compiler isn't that smart.
In your third function, it does appear that one could be refered to without having first been initialized.
First: You set x but do not use it. It's a local variable that gets set but it's dropped as soon as the function returns.
Second: There might be values that makes it so that your best_mem/worst_mem never gets set in your if/else, but you are using them later on. If they haven't been set, they contain garbage if not initialized.
Third: While it shouldn't happen that you try to use an uninitialized variable in your code, it still looks weird and compiler doesn't see that it won't happen first time.
When you get compiler warnings, treat is as you are doing something wrong or rather not recommended and that it could be done in a better way.
The x variable is only used on the left hand side (i.e. assigned a value). You are not using that value on the right hand side or pass it to a function.
It may be possible to get to the end of the loop for(i = 0; i < POPSIZE - 1; i++) without those variables given a value. Why not set them in the declaration.
The call to random_Xover(one,mem); could be called when one is not set. Change the line int mem,one; to int mem,one = <some value>;

How cast array[4] to array[2][2]?

I have a array short frame[4] and I want it as a function parameter as short frame[2][2]
How can I cast it? I tried different things (like *(short [2][2])&frame[0]*), but I still get error messages.
Also not working is if I declare the function with void function(short frame[2][2])
and call the function with function(&frame[0]) while frame is a short frame[4];
I don't think it is a good pratice, anyway:
f((short (*)[2])a);
This works here, albeit with a warning.
#include <stdio.h>
void function(short frame[2][2])
{
for (int i = 0; i < 2; i++)
for (int j = 0; j < 2; j++)
printf("%d ", frame[i][j]);
printf("\n");
}
int main()
{
short frame[4] = { 0, 1, 2, 3 };
function(&frame[0]);
return 0;
}
What error message do you get?
You can't cast between different dimensional arrays.
It wouldn't know which way round you wanted it.
You'll have to write a function.
In pseudocode:
function castArray(short[4] input){
short[2][2] output = new short[2][2];
output[0][0] = input[0];
output[0][1] = input[1];
output[1][0] = input[2];
output[1][1] = input[3];
return output;
}
You achieve it an easy way like this :
Converting 1-D array into 2-D array
short frame[MAX];
short dup_frame[ROW][COL];
int i,j,k;
for(i = 0 ; i < MAX ; i++)
{
j= i / ROW ; // you can do it by i / COL also
k= i % ROW ; // you can do it by i % COL also
dup_frame[j][k] = frame[i];
}

Resources