Interleaving array in C - c

I posted earlier, but I did not properly format or add my code. Say I have an int array x = [1,2,3]. Given a value i, I want to create an array x^i, such that, if i = 3, array x^i = [1,1,1,2,2,2,3,3,3]. If i = 5, array x^i = [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5]. I am dynamically allocating memory for this.
However, my code for i = 3 is creating an array = [1,2,3,1,2,3,1,2,3]. I've tried many different things, and I got something like [1,1,1,1,1,1,1,1,1] or [3,3,3,3,3,3,3,3,3] but never the correct answer.
Here is my code:
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i){
int i, j, k, count = 0, max_repeat = 0;
while(min_i <= max_i){
int repeats = (max_i + min_i)/2;
int * temp = realloc(X, size_x * sizeof(int) * repeats);
X = temp;
for(k = 0; k < size_x; ++k){
int idx = size_x - k -1;
temp = &X[idx];
for(j = 0; j < repeats; ++j){
X[idx * repeats + j] = *temp;
}
}
printf("New X: ");
for(i = 0; i < size_x * repeats; i++){
printf("%d ", X[i]);
}
int count = 0;
for(i = 0; i < size_x * repeats; i++){
for(j = 0; j < size_a; j++){
if(A[j] == X[i]){
count++;
i++;
}
}
}
if (count == size_x * repeats){
printf("Low: %d Mid %d High % d Passes\n", min_i, repeats, max_i);
min_i = repeats + 1;
}
else
printf("Low: %d Mid %d High % d Fails\n", min_i, repeats, max_i);
max_i = repeats - 1;
}
}
the variable repeats represents the value i in x^i.
The output is this:
Old X: 1 2 3
New X: 1 1 1 2 2 2 3 3 3 Low: 0 Mid 3 High 6 Fails
New X: 1 1 1 Low: 0 Mid 1 High 2 Fails
New X: Low: 0 Mid 0 High 0 Fails
The first iteration is correct, however, the second iteration should not be [1,1,1], it should be [1,2,3].
Where am I going wrong?

Here you go:
int misleading_function_names_is_bad_practice(size_t xsize, int x[xsize], size_t i)
{
void * const tmp = realloc(x, xsize * sizeof(*x) * i);
if (tmp == NULL) {
return -__LINE__;
}
x = tmp;
for (size_t k = 0; k < xsize; ++k) {
// index of the last original digit counting down
const size_t idx = xsize - k - 1;
const int tmp = x[idx];
for (size_t l = 0; l < i; ++l) {
// fill from the back
x[idx * i + l] = tmp;
}
}
return 0;
}
Live example available at onlinegdb.

Related

As a result of processing arrays -nan(ind)

I am writing a program that creates arrays of a given length and manipulates them. You cannot use other libraries.
First, an array M1 of length N is formed, after which an array M2 of length N is formed/2.
In the M1 array, the division by Pi operation is applied to each element, followed by elevation to the third power.
Then, in the M2 array, each element is alternately added to the previous one, and the tangent modulus operation is applied to the result of addition.
After that, exponentiation is applied to all elements of the M1 and M2 array with the same indexes and the resulting array is sorted by dwarf sorting.
And at the end, the sum of the sines of the elements of the M2 array is calculated, which, when divided by the minimum non-zero element of the M2 array, give an even number.
The problem is that the result X gives is -nan(ind). I can't figure out exactly where the error is.
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
const int A = 441;
const double PI = 3.1415926535897931159979635;
inline void dwarf_sort(double* array, int size) {
size_t i = 1;
while (i < size) {
if (i == 0) {
i = 1;
}
if (array[i - 1] <= array[i]) {
++i;
}
else
{
long tmp = array[i];
array[i] = array[i - 1];
array[i - 1] = tmp;
--i;
}
}
}
inline double reduce(double* array, int size) {
size_t i;
double min = RAND_MAX, sum = 0;
for (i = 0; i < size; ++i) {
if (array[i] < min && array[i] != 0) {
min = array[i];
}
}
for (i = 0; i < size; ++i) {
if ((int)(array[i] / min) % 2 == 0) {
sum += sin(array[i]);
}
}
return sum;
}
int main(int argc, char* argv[])
{
int i, N, j;
double* M1 = NULL, * M2 = NULL, * M2_copy = NULL;
double X;
unsigned int seed = 0;
N = atoi(argv[1]); /* N равен первому параметру командной строки */
M1 = malloc(N * sizeof(double));
M2 = malloc(N / 2 * sizeof(double));
M2_copy = malloc(N / 2 * sizeof(double));
for (i = 0; i < 100; i++)
{
seed = i;
srand(i);
/*generate*/
for (j = 0; j < N; ++j) {
M1[j] = (rand_r(&seed) % A) + 1;
}
for (j = 0; j < N / 2; ++j) {
M2[j] = (rand_r(&seed) % (10 * A)) + 1;
}
/*map*/
for (j = 0; j < N; ++j)
{
M1[j] = pow(M1[j] / PI, 3);
}
for (j = 0; j < N / 2; ++j) {
M2_copy[j] = M2[j];
}
M2[0] = fabs(tan(M2_copy[0]));
for (j = 0; j < N / 2; ++j) {
M2[j] = fabs(tan(M2[j] + M2_copy[j]));
}
/*merge*/
for (j = 0; j < N / 2; ++j) {
M2[j] = pow(M1[j], M2[j]);
}
/*sort*/
dwarf_sort(M2, N / 2);
/*sort*/
X = reduce(M2, N / 2);
}
printf("\nN=%d.\n", N);
printf("X=%f\n", X);
return 0;
}
Knowledgeable people, does anyone see where my mistake is? I think I'm putting the wrong data types to the variables, but I still can't solve the problem.
Replace the /* merge */ part with this:
/*merge*/
for (j = 0; j < N / 2; ++j) {
printf("%f %f ", M1[j], M2[j]);
M2[j] = pow(M1[j], M2[j]);
printf("%f\n", M2[j]);
}
This will print the values and the results of the pow operation. You'll see that some of these values are huge resulting in an capacity overflow of double.
Something like pow(593419.97, 31.80) will not end well.

My for loop is adding +1 excess and i do not know why

Basically im trying to make a program that loops through the given array, and checks if the right element is 2x bigger than the left one, if true inserts average value of those two elements in the middle. After that, it prints out the array with inserted elements, and then loops through the array again, counting how many times a certain number appears. I coded all of it successfully using pen and paper and writing the problem into smaller chunks and then coding it in C but the problem is when i enter 100 zeros (one hundred zeros). the program prints out that the number 0 is repeated 200 times instead of 199. I do not know why. And sorry for the code being bad, my current task is to get good at solving problems with pen and paper, after i become decent at that and develop my logic, i will try making the code simpler.
Input sample:
Enter the number of elements: 100
Enter the array: 0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
After adding middle element: 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002.33412e-310
The number is repeated 200 time/s
My code
#include <math.h>
#include <stdio.h>
#define EPSILON 0.0001
int main() {
int n, i, j, k, digit, length = 0, digit_array[10] = {0};
double array[200], temp;
do {
printf("Enter number of elements: ");
scanf("%d", &n);
} while (n <= 0 || n >= 101);
printf("Enter elements: ");
length = n;
for (i = 0; i < length; i++)
scanf("%lf", &array[i]);
for (i = 0; i < length; i++) {
temp = array[i] + array[i];
if (fabs(temp - array[i + 1]) < EPSILON) {
for (j = length; j > i + 1; j--)
array[j] = array[j - 1];
array[i + 1] = (array[i] + array[i + 1]) / 2.;
i++;
length++;
}
}
printf("After adding middle element: \n");
for (i = 0; i < length; i++)
printf("%g ", array[i]);
for (i = 0; i < length; i++) {
temp = array[i];
digit = ((int)(temp * 10)) % 10;
digit_array[digit]++;
}
printf("\n");
for (i = 0; i < 10; i++) {
if (digit_array[i] != 0)
printf("Number %d is repeated %d time/s.\n", i, digit_array[i]);
}
return 0;
}
Rather than constantly shifting the array, it's a lot easier and faster to use two arrays. All you need is this:
// Inputs:
// n: The number of inputs.
// a: An array of at least n doubles containing the inputs.
// b: An array of at least n*2-1 doubles that will containing the outputs.
// Outputs:
// m: The number of outputs.
// b: An array of at least m doubles containing the outputs.
size_t i = 0;
size_t j = 0;
double prev = b[j++] = a[i++];
while (i < n) {
double next = a[i];
if (fabs(prev*2 - next) < EPSILON) { // If a[i-1] exactly equal a[i]*2.
b[j++] = next / 2.0 + prev / 2.0; // Or: b[j++] = prev * 1.5;
}
prev = b[j++] = a[i++];
}
size_t m = j;
Regarding prev * 1.5:
average(next, prev)
= ( next + prev ) / 2
= ( prev * 2 + prev ) / 2
= ( prev * 3 ) / 2
= prev * 1.5
Included in a proper function:
int f(double *a, size_t n, double **b_ptr, size_t *m_ptr) {
double b = malloc( (n*2-1) * sizeof(double) ); // We need up to this much.
if (b == NULL) {
*b_ptr = NULL;
return 0;
}
size_t i = 0;
size_t j = 0;
double prev = b[j++] = a[i++];
while (i < n) {
double next = a[i];
if (fabs(prev*2 - next) < EPSILON) { // If a[i-1] exactly equal a[i]*2.
b[j++] = next / 2.0 + prev / 2.0; // Or: b[j++] = prev * 1.5;
}
prev = b[j++] = a[i++];
}
b = realloc(b, j * sizeof(double)); // Free the excess. (Optional)
size_t m = j;
*b_ptr = b;
*m_ptr = m;
return 1;
}

problem calculating the inverse of a matrix

I'm trying to calculate the inverse of a square matrix of any rank N x N. I'm using a struct to store the values of the matrix which I can to effectively and I am already able to calculate the determinant. But there must be some issue with the inverse function. This is the code
struct m{
size_t row;
size_t col;
double *data;
};
void inverse(size_t n, struct m *A) /*Calculate the inverse of A */
{
size_t i,j,i_count,j_count, count=0;
double det = determinant(n, A);
size_t id = 0;
double *d;
struct m C; /*The Adjoint matrix */
C.data = malloc(sizeof(double) * n * n);
C.row = n;
C.col = n;
struct m *minor; /*matrices obtained by removing the i row and j column*/
if (!(minor = malloc(n*n*(n+1)*sizeof *minor))) {
perror ("malloc-minor");
exit(-1);
}
if (det == 0){
printf("The matrix is singular\n");
exit(1);
}
for(id=0; id < n*n; id++){
d = minor[id].data = malloc(sizeof(double) * (n-1) * (n-1));
for(count=0; count < n; count++)
{
//Creating array of Minors
i_count = 0;
for(i = 0; i < n; i++)
{
j_count=0;
for(j = 0; j < n; j++)
{
if(j == count)
continue; // don't copy the minor column element
*d = A->data[i * A->col + j];
d++;
j_count++;
}
i_count++;
}
}
}
for(id=0; id < n*n; id++){
for(i=0; i < n; i++){
for(j=0; j < n; j++)
C.data[i * C.col + j] = determinant(n-1,&minor[id]);//Recursive call
}
}
transpose(&C);
scalar_product(1/det, &C);
*A = C;
}
The determinant is calculated recursively with this algorithm:
double determinant(size_t n, struct m *A)
{
size_t i,j,i_count,j_count, count=0;
double det = 0;
if(n < 1)
{
printf("Error\n");
exit(1);
}
if(n==1) return A->data[0];
else if(n==2) return (A->data[0]* A->data[1 * A->col + 1] - A->data[0 + 1] * A->data[1*A->col + 0]);
else{
struct m C;
C.row = A->row-1;
C.col = A->col-1;
C.data = malloc(sizeof(double) * (A->row-1) * (A->col-1));
for(count=0; count < n; count++)
{
//Creating array of Minors
i_count = 0;
for(i = 1; i < n; i++)
{
j_count=0;
for(j = 0; j < n; j++)
{
if(j == count)
continue; // don't copy the minor column element
C.data[i_count * C.col + j_count] = A->data[i * A->col + j];
j_count++;
}
i_count++;
}
det += pow(-1, count) * A->data[count] * determinant(n-1,&C);//Recursive call
}
free(C.data);
return det;
}
}
You can find the complete code here: https://ideone.com/gQRwVu.
Use some other variable in the loop after :
det + =pow(-1,count) * A->data[count] *determinant (n-1,&C)
Your calculation of the inverse doesn't quite correspond to the algorithm described e. g. for Inverse of a Matrix
using Minors, Cofactors and Adjugate, even taken into account that you for now omitted the adjugate and division step. Compare your outermost for loop in inverse() to this working implementation:
double Rdata[(n-1)*(n-1)]; // remaining data values
struct m R = { n-1, n-1, Rdata }; // matrix structure for them
for (count = 0; count < n*n; count++) // Create n*n Matrix of Minors
{
int row = count/n, col = count%n;
for (i_count = i = 0; i < n; i++)
if (i != row) // don't copy the current row
{
for (j_count = j = 0; j < n; j++)
if (j != col) // don't copy the current column
Rdata[i_count*R.col+j_count++] = A->data[i*A->col+j];
i_count++;
}
// transpose by swapping row and column
C.data[col*C.col+row] = pow(-1, row&1 ^ col&1) * determinant(n-1, &R) / det;
}
It yields for the given input data the correct inverse matrix
1 2 -4.5
0 -1 1.5
0 0 0.5
(already transposed and divided by the determinant of the original matrix).
Minor notes:
The *A = C; at the end of inverse() loses the original data pointer of *A.
The formatting function f() is wrong for negative values, since the fraction is also negative in this case. You could write if (fabs(f)<.00001).

binary search counter not updating

I have two arrays, a fixed Array A and a dynamically updating array X. I am trying to find the max interleaving factor i for X^i, such that X^i is a subsequence of A.
My X and A arrays are populating correctly, as I've tested them on each iteration through the binary search. However, my counter is not.
Here is my code:
void binary_search(int size_a, int * A, int size_x, int *X, int max_i, int min_i){
int j, k, max_repeat = 0;
while(min_i <= max_i){
int i = 0, count = 0, repeats = (max_i + min_i)/2;
printf("\n");
int * temp = malloc(size_x * sizeof(int) * repeats);
for(k = 0; k < size_x; ++k){
for(j = 0; j < repeats; ++j){
temp[k * repeats + j] = X[k];
}
}
printf("New X: ");
for(i = 0; i < size_x * repeats; i++){
printf("%d ", temp[i]);
}
printf("A: ");
for (i = 0; i < size_a; i++){
printf("%d ", A[i]);
}
for(j = 0; j < size_a; j++){
if(A[j] == temp[i]){
count++;
i++;
}
}
printf("Count: %d", count);
if (count >= size_x * repeats){
printf("Low: %d Mid %d High % d Passes\n", min_i, repeats, max_i);
min_i = repeats + 1;
max_repeat++;
}
else{
printf("Low: %d Mid %d High % d Fails\n", min_i, repeats, max_i);
max_i = repeats - 1;
}
free(temp);
}
printf("Max repeat: %d", max_repeat);
}
Array A = [4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1,4,3,2,1] and X = [1,2,3] initially. So X^3 = [1,1,1,2,2,2,3,3,3]. This should fail, because count is not > = size_x * repeats (count should be 5 on this iteration), and it does, but count = 0 throughout each iteration when it should clearly update. What am I missing? I have been staring at this for way to long, so I'm sure it's something simple.
EDIT Expected value:
Low 0 Mid 3 High 6 Fails
Low 0 Mid 1 High 2 Passes
Low 2 Mid 2 High 2 Fails
Actual value:
Low 0 Mid 3 High 6 Fails
Low 0 Mid 1 High 2 Fails
Low 0 Mid 0 High 0 Passes

Inverse of a binary matrix in C

I have a binary matrix (zeros and ones) D[][] of dimension nxn where n is large (approximately around 1500 - 2000). I want to find the inverse of this matrix in C.
Since I'm new to C, I started with a 3 x 3 matrix and working around to generalize it to N x N. This works for int values, however since I'm working with binary 1's and 0's. In this implementation, I need unsigned int values.
I could find many solutions for int values but I didn't come across any solution for unsigned int. I'd like to find the inverse of a N x N binary matrix without using any external libraries like blas/lapack. It'd be great if anyone could provide a lead on M x N matrix.
Please note that I need inverse of a matrix, not the pseudo-inverse.
/* To find the inverse of a matrix using LU decomposition */
/* standard Headers */
#include<math.h>
#include<stdio.h>
int main() {
/* Variable declarations */
int i,j;
unsigned int n,m;
unsigned int rows,cols;
unsigned int D[3][3], d[3], C[3][3];
unsigned int x, s[3][3];
unsigned int y[3];
void LU();
n = 2;
rows=3;cols=3;
/* the matrix to be inverted */
D[0][0] = 1;
D[0][1] = 1;
D[0][2] = 0;
D[1][0] = 0;
D[1][1] = 1;
D[1][2] = 0;
D[2][0] = 1;
D[2][1] = 1;
D[2][2] = 1;
/* Store the matrix value for camparison later.
this is just to check the results, we don't need this
array for the program to work */
for (m = 0; m <= rows-1; m++) {
for (j = 0; j <= cols-1; j++) {
C[m][j] = D[m][j];
}
}
/* Call a sub-function to calculate the LU decomposed matrix. Note that
we pass the two dimensional array [D] to the function and get it back */
LU(D, n);
printf(" \n");
printf("The matrix LU decomposed \n");
for (m = 0; m <= rows-1; m++) {
for (j = 0; j <= cols-1; j++){
printf(" %d \t", D[m][j]);
}
printf("\n");
}
/* TO FIND THE INVERSE */
/* to find the inverse we solve [D][y]=[d] with only one element in
the [d] array put equal to one at a time */
for (m = 0; m <= rows-1; m++) {
d[0] = 0;
d[1] = 0;
d[2] = 0;
d[m] = 1;
for (i = 0; i <= n; i++) {
x = 0;
for (j = 0; j <= i - 1; j++){
x = x + D[i][j] * y[j];
}
y[i] = (d[i] - x);
}
for (i = n; i >= 0; i--) {
x = 0;
for (j = i + 1; j <= n; j++) {
x = x + D[i][j] * s[j][m];
}
s[i][m] = (y[i] - x) / D[i][i];
}
}
/* Print the inverse matrix */
printf("The Inverse Matrix\n");
for (m = 0; m <= rows-1; m++) {
for (j = 0; j <= cols-1; j++){
printf(" %d \t", s[m][j]);
}
printf("\n");
}
/* check that the product of the matrix with its iverse results
is indeed a unit matrix */
printf("The product\n");
for (m = 0; m <= rows-1; m++) {
for (j = 0; j <= cols-1; j++){
x = 0;
for (i = 0; i <= 2; i++) {
x = x + C[m][i] * s[i][j];
}
//printf(" %d %d %f \n", m, j, x);
printf("%d \t",x);
}
printf("\n");
}
return 0;
}
/* The function that calcualtes the LU deomposed matrix.
Note that it receives the matrix as a two dimensional array
of pointers. Any change made to [D] here will also change its
value in the main function. So there is no need of an explicit
"return" statement and the function is of type "void". */
void LU(int (*D)[3][3], int n) {
int i, j, k;
int x;
printf("The matrix \n");
for (j = 0; j <= 2; j++) {
printf(" %d %d %d \n", (*D)[j][0], (*D)[j][1], (*D)[j][2]);
}
for (k = 0; k <= n - 1; k++) {
for (j = k + 1; j <= n; j++) {
x = (*D)[j][k] / (*D)[k][k];
for (i = k; i <= n; i++) {
(*D)[j][i] = (*D)[j][i] - x * (*D)[k][i];
}
(*D)[j][k] = x;
}
}
}
This is just a sample example that I tried and I have -1 values in the inverse matrix which is my main concern. I have 1000 x 1000 matrix of binary values and the inverse should also be in binary.
The matrix:
1 1 0
0 1 0
1 1 1
The matrix LU decomposed:
1 1 0
0 1 0
1 0 1
The Inverse Matrix:
1 -1 0
0 1 0
-1 0 1
The product:
1 0 0
0 1 0
0 0 1

Resources