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.
Related
This is the question:
https://www.hackerrank.com/challenges/lisa-workbook/problem.
My code passes all the test cases except one. The message I get is just Run Time Error. Even if I return 0 at the beginning of the function that I am supposed to implement, I still get this error, while in all other test cases I get Wrong Answer.
This is not the only question on hacker rank where this happened. In the last couple of days I encountered 3 or 4 more questions with that one odd case that was always giving a runtime error. In the end, I had to implement a Python 3 solution (with the same logic), which passed all the test cases, to solve these problems.
I wonder if this is a bug on the website or if I am understanding something wrongly. Here is my function implementation for this problem:
int workbook(int n, int k, int arr_count, int* arr)
{
int tmp = 1, specprob = 0;
int *chstart = malloc(n * sizeof(int));
int *chend = malloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
chstart[i] = tmp;
tmp += arr[i] / k - 1;
if (arr[i] % k != 0) {
tmp++;
}
chend[i] = tmp;
tmp++;
if (!(arr[i] < chstart[i])) {
int qno = 0, chpage = 1, iqno = 0;
for (int j = chstart[i]; j < chend[i] + 1; j++) {
if (chpage * k <= arr[i]) {
qno += k;
} else {
qno += (k - (chpage * k - arr[i]));
}
if (j > iqno && j < qno + 1) {
specprob++;
}
iqno = qno;
chpage++;
}
}
}
return specprob;
}
It looks like a bug, since when you run the empty function with just a return 0; it gives the same runtime error.
For the moment though, if you don't mind too much about the different language, you could make a few minor changes to the code to make it compile for C++ (don't forget to change the language selection too):
int workbook(int n, int k, vector<int> arr)
{
int tmp = 1, specprob = 0;
int *chstart = (int*)malloc(n * sizeof(int));
int *chend = (int*)malloc(n * sizeof(int));
for (int i = 0; i < n; i++)
{
chstart[i] = tmp;
tmp += arr[i] / k - 1;
if (arr[i] % k != 0)
{
tmp++;
}
chend[i] = tmp;
tmp++;
if (!(arr[i] < chstart[i]))
{
int qno = 0, chpage = 1, iqno = 0;
for (int j = chstart[i]; j < chend[i] + 1; j++)
{
if (chpage * k <= arr[i])
{
qno += k;
}
else
{
qno += (k - (chpage * k - arr[i]));
}
if (j > iqno && j < qno + 1)
{
specprob++;
}
iqno = qno;
chpage++;
}
}
}
return specprob;
}
hello i used gauss jordan for 1d but i didnt
i want to find 1d matrix inverse. I found determinant but i dont know inverse of this matrix
Hello my dear friends
Our matrixes:
double A[] = {6, 6 ,2, 4, 9 ,7, 4, 3 ,3};
double B[] = {6, 6 ,2, 4, 9 ,7, 4, 3 ,3};
double Final[9];
Function to calculate determinant:
int Inverse(double *A, double *C, int N){
int n = N;
int i, j, k;
float a[10][10] = { 0.0 };
double C[9] = { 0.0 };
float pivot = 0.0;
float factor = 0.0;
double sum = 0.0; ``` variables
for (k = 1; k <= n - 1; k++)
{
if (a[k][k] == 0.0)
{
printf("error");
}
else
{
pivot = a[k][k];
for (j = k; j <= n + 1; j++)
a[k][j] = a[k][j] / pivot;
for (i = k + 1; i <= n; i++)
{
factor = a[i][k];
for (j = k; j <= n + 1; j++)
{
a[i][j] = a[i][j] - factor * a[k][j];
}
}
}
if (a[n][n] == 0)
printf("error");
else
{
C[n] = a[n][n + 1] / a[n][n];
for (i = n - 1; i >= 1; i--)
{
sum = 0.0;
for (j = i + 1; j <= n; j++)
sum = sum + a[i][j] * C[j];
C[i] = (a[i][n + 1] - sum) / a[i][i];
}
}
}
for (i = 1; i <= n; i++)
{
printf("\n\tx[%1d]=%10.4f", i, C[i]);
}
system("PAUSE");
return 0;
}
Although I tried very hard, I couldn't find the opposite in c programming for a 1x1 dimensional matrix. Output always generates 0. Can you help me where I could be making a mistake. Thank you.
It appears you are using C as an output parameter (to store the inverse); however, you also declare a local variable of the same name in the function. This causes the local variable to shadow (i.e.: hide) the output parameter; thus, changes you make to the C in the function do not affect the C the calling function sees.
To fix this issue, you need to remove the line double C[9] = {0}; from your function.
I created a cross-correlation algorithm, and I am trying to maximize its performance by reducing the time it takes for it to run. First of all, I reduced the number of function calls within the "crossCorrelationV2" function. Second, I created several macros at the top of the program for constants. Third, I reduced the number of loops that are inside the "crossCorrelationV2" function. The code that you see is the most recent code that I have.
Are there any other methods I can use to try and reduce the processing time of my code?
Let's assume that I am only focused on the functions "crossCorrelationV2" and "createAnalyzingWave".
I would be glad for any advice, whether in general about programming or pertaining to those two specific functions; I am a beginner programmer. Thanks.
#include <stdio.h>
#include <stdlib.h>
#define ARRAYSIZE 4096
#define PULSESNUMBER 16
#define DATAFREQ 1300
// Print the contents of the array onto the console.
void printArray(double array[], int size){
int k;
for (k = 0; k < size; k++){
printf("%lf ", array[k]);
}
printf("\n");
}
// Creates analyzing square wave. This square wave has unity (1) magnitude.
// The number of high values in each period is determined by high values = (analyzingT/2) / time increment
void createAnalyzingWave(double analyzingFreq, double wave[]){
int highValues = (1 / analyzingFreq) * 0.5 / ((PULSESNUMBER * (1 / DATAFREQ) / ARRAYSIZE));
int counter = 0;
int p;
for(p = 1; p <= ARRAYSIZE; p++){
if ((counter % 2) == 0){
wave[p - 1] = 1;
} else{
wave[p - 1] = 0;
}
if (p % highValues == 0){
counter++;
}
}
}
// Creates data square wave (for testing purposes, for the real implementation actual ADC data will be used). This
// square wave has unity magnitude.
// The number of high values in each period is determined by high values = array size / (2 * number of pulses)
void createDataWave(double wave[]){
int highValues = ARRAYSIZE / (2 * PULSESNUMBER);
int counter = 0;
int p;
for(p = 0; p < ARRAYSIZE; p++){
if ((counter % 2) == 0){
wave[p] = 1;
} else{
wave[p] = 0;
}
if ((p + 1) % highValues == 0){
counter++;
}
}
}
// Finds the average of all the values inside an array
double arrayAverage(double array[], int size){
int i;
double sum = 0;
// Same thing as for(i = 0; i < arraySize; i++)
for(i = size; i--; ){
sum = array[i] + sum;
}
return sum / size;
}
// Cross-Correlation algorithm
double crossCorrelationV2(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
double bigAnalyzingArray[bigArraySize];
int i;
int b;
// Set first few elements of the array equal to analyzingWave
// Set remainder of big analyzing array to 0
for(i = 0; i < ARRAYSIZE; i++){
bigAnalyzingArray[i] = analyzingWave[i];
bigAnalyzingArray[i + ARRAYSIZE] = 0;
}
double maxCorrelationValue = 0;
double currentCorrelationValue;
// "Beginning" of correlation algorithm proper
for(i = 0; i < bigArraySize; i++){
currentCorrelationValue = 0;
for(b = lastBigArrayIndex; b > 0; b--){
if (b >= lastArrayIndex){
currentCorrelationValue = dataWave[b - lastBigArrayIndex / 2] * bigAnalyzingArray[b] + currentCorrelationValue;
}
bigAnalyzingArray[b] = bigAnalyzingArray[b - 1];
}
bigAnalyzingArray[0] = 0;
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
return maxCorrelationValue;
}
int main(){
int samplesNumber = 25;
double analyzingFreq = 1300;
double analyzingWave[ARRAYSIZE];
double dataWave[ARRAYSIZE];
createAnalyzingWave(analyzingFreq, analyzingWave);
//createDataWave(arraySize, pulsesNumber, dataWave);
double maximumCorrelationArray[samplesNumber];
int i;
for(i = 0; i < samplesNumber; i++){
createDataWave(dataWave);
maximumCorrelationArray[i] = crossCorrelationV2(dataWave, analyzingWave);
}
printf("Average of the array values: %lf\n", arrayAverage(maximumCorrelationArray, samplesNumber));
return 0;
}
The first point is that you are explicitly shifting the analizingData array, this way you are required twice as much memory and moving the items is about 50% of your time. In a test here using crossCorrelationV2 takes 4.1 seconds, with the implementation crossCorrelationV3 it runs in ~2.0 seconds.
The next thing is that you are spending time multiplying by zero on the padded array, removing that, and also removing the padding, and simplifying the indices we end with crossCorrelationV4 that makes the program to run in ~1.0 second.
// Cross-Correlation algorithm
double crossCorrelationV3(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
double bigAnalyzingArray[bigArraySize];
int i;
int b;
// Set first few elements of the array equal to analyzingWave
// Set remainder of big analyzing array to 0
for(i = 0; i < ARRAYSIZE; i++){
bigAnalyzingArray[i] = analyzingWave[i];
bigAnalyzingArray[i + ARRAYSIZE] = 0;
}
double maxCorrelationValue = 0;
double currentCorrelationValue;
// "Beginning" of correlation algorithm proper
for(i = 0; i < bigArraySize; i++){
currentCorrelationValue = 0;
// Instead of checking if b >= lastArrayIndex inside the loop I use it as
// a stopping condition.
for(b = lastBigArrayIndex; b >= lastArrayIndex; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue = dataWave[b - lastBigArrayIndex / 2] * bigAnalyzingArray[b - i] + currentCorrelationValue;
}
bigAnalyzingArray[0] = 0;
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
return maxCorrelationValue;
}
// Cross-Correlation algorithm
double crossCorrelationV4(double dataWave[], double analyzingWave[]){
int bigArraySize = (2 * ARRAYSIZE) - 1;
// Expand analyzing array into array of size 2arraySize-1
int lastArrayIndex = ARRAYSIZE - 1;
int lastBigArrayIndex = 2 * ARRAYSIZE - 2; //bigArraySize - 1; //2 * arraySize - 2;
// I will not allocate the bigAnalizingArray here
// double bigAnalyzingArray[bigArraySize];
int i;
int b;
// I will not copy the analizingWave to bigAnalyzingArray
// for(i = 0; i < ARRAYSIZE; i++){
// bigAnalyzingArray[i] = analyzingWave[i];
// bigAnalyzingArray[i + ARRAYSIZE] = 0;
// }
double maxCorrelationValue = 0;
double currentCorrelationValue;
// Compute the correlation by symmetric paris
// the idea here is to simplify the indices of the inner loops since
// they are computed more times.
for(i = 0; i < lastArrayIndex; i++){
currentCorrelationValue = 0;
for(b = lastArrayIndex - i; b >= 0; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue += dataWave[b] * analyzingWave[b + i];
}
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
if(i != 0){
currentCorrelationValue = 0;
// Correlate shifting to the other side
for(b = lastArrayIndex - i; b >= 0; b--){
// instead of shifting bitAnalizing[b] = bigAnalyzingArray[b-1] every iteration
// I simply use bigAnalizingArray[b-i]
currentCorrelationValue += dataWave[b + i] * analyzingWave[b];
}
if (currentCorrelationValue > maxCorrelationValue){
maxCorrelationValue = currentCorrelationValue;
}
}
}
return maxCorrelationValue;
}
If you want more optimization you can unroll some iterations of the loop and enable some compiler optimizations like vector extension.
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).
I'm working on a class assignment and I've run into an issue I haven't been able to figure out. I'm implementing the Ford-Fulkerson algorithm using BFS to find max flow. But while trying to set my Residual Capacity matrix to the given capacity, I hit a segmentation fault. In the test code we received, I can see that the original capacity matrix was passed by value by its address, but I have a feeling that in my code I'm not interacting with it the way I think I am? Which leads me to believe that I may have the same issue recurring elsewhere. I worked with gdb and saw that I hit a segmentation fault on this line here in my nested for loop :
resCap[i][j] = *(capacity + i*n + j);
However, nothing I have tried has worked for me though so I am pretty stumped.
void maximum_flow(int n, int s, int t, int *capacity, int *flow)
{
int i, j, resCap[n][n], path[n]; // residual capacity and BFS augmenting path
int min_path = INT_MAX; // min of the augmenting path
// Assign residual capacity equal to the given capacity
for (i = 0; i < n; i++)
for (j = 0; j < n; j++)
{
resCap[i][j] = *(capacity + i*n + j);
*(flow + i*n + j) = 0; // no initial flow
}
// Augment path with BFS from source to sink
while (bfs(n, s, t, &(resCap[0][0]), path))
{
// find min of the augmenting path
for (j = t; j != s; j = path[j])
{
i = path[j];
min_path = min(min_path, resCap[i][j]);
}
// update residual capacities and flows on both directions
for (j = t; j != s; j = path[j])
{
i = path[j];
if(*(capacity + i*n + j) > 0)
*(flow + i*n + j) += min_flow_path;
else
*(flow + j*n + i) -= min_flow_path;
resCap[i][j] -= min_flow_path;
resCap[j][i] += min_flow_path;
}
}
}
And here is the test code provided to us in case it is needed:
int main(void)
{ int cap[1000][1000], flow[1000][1000];
int i,j, flowsum;
for(i=0; i< 1000; i++)
for( j =0; j< 1000; j++ )
cap[i][j] = 0;
for(i=0; i<499; i++)
for( j=i+1; j<500; j++)
cap[i][j] = 2;
for(i=1; i<500; i++)
cap[i][500 + (i/2)] =4;
for(i=500; i < 750; i++ )
{ cap[i][i-250]=3;
cap[i][750] = 1;
cap[i][751] = 1;
cap[i][752] = 5;
}
cap[751][753] = 5;
cap[752][753] = 5;
cap[753][750] = 20;
for( i=754; i< 999; i++)
{ cap[753][i]=1;
cap[i][500]=3;
cap[i][498]=5;
cap[i][1] = 100;
}
cap[900][999] = 1;
cap[910][999] = 1;
cap[920][999] = 1;
cap[930][999] = 1;
cap[940][999] = 1;
cap[950][999] = 1;
cap[960][999] = 1;
cap[970][999] = 1;
cap[980][999] = 1;
cap[990][999] = 1;
printf("prepared capacity matrix, now executing maxflow code\n");
maximum_flow(1000,0,999,&(cap[0][0]),&(flow[0][0]));
for(i=0; i<=999; i++)
for(j=0; j<=999; j++)
{ if( flow[i][j] > cap[i][j] )
{ printf("Capacity violated\n"); exit(0);}
}
flowsum = 0;
for(i=0; i<=999; i++)
flowsum += flow[0][i];
printf("Outflow of 0 is %d, should be 10\n", flowsum);
flowsum = 0;
for(i=0; i<=999; i++)
flowsum += flow[i][999];
printf("Inflow of 999 is %d, should be 10\n", flowsum);
printf("End Test\n");
}
This line is likely going to segfault, it does using Clang.
int i, j, resCap[n][n], path[n];
You're declaring a very large array on the stack. Just how big can be seen when you try and allocated it using calloc. Try this instead and don't forget to free it using the same sort of loop.
int **resCap2 = calloc(1, n * sizeof(int *));
assert(resCap2);
for (i = 0; i < n; i++) {
resCap2[i] = calloc(1, n * sizeof(int));
assert(resCap2[i]);
}
This is a lot of space ie
(1000 * sizeof(int*) * (1000 * n * sizeof(int)))