C Signal Processing - Implementation Doubts - c

I´m trying to adapt a algorithm from matlab.
My algorithm:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <cwp.h>
#define MAX_LINES 225000
#define MAX_SAMPLE 2500
#define LMAX 200000
#define LFILT 128
#define TamConv 2580
#define LENGTH_(x) (sizeof(x)/sizeof(x[0]))
int
main(argc, argv)
int argc;
char **argv;
{
FILE *fp;
float data[MAX_LINES], samples[MAX_SAMPLE], mexh[81], values;
float j, pi, mean_atraso, passo, total_passo;
double escala[] = {1, 2, 4, 8};
size_t escala_len,k,l;
int i,m,n;
long unsigned int tex;
float convol[TamConv],aux1[TamConv],aux2[TamConv];
pi = M_PI;
/*
Leitura dos Dados
*/
/*
if (argv[1] == NULL) {
perror("Sem arquivo de texto!");
return 1;
} */
fp = fopen("exames.txt", "r");
if (fp == NULL) {
perror("Arquivo vazio!");
return 1;
}
while((fscanf(fp, "%lf", &values) && (i < MAX_LINES))) {
data[i] = values;
if (i <= MAX_SAMPLE) {
samples[i] = values;
mean_atraso += values;
}
i++;
}
fclose(fp);
printf("DATA: %lu \n", LENGTH_(data)); // Tamanho do arquivo
/*
Calcula a tal media mean_atraso
*/
mean_atraso /= MAX_SAMPLE;
for (i=0; i<=MAX_SAMPLE; i++) {
samples[i] -= mean_atraso;
}
/*
Chapéu Mexicano
*/
escala_len = LENGTH_(escala);
printf("%zu \n", escala_len);
i=0;
while (i < escala_len) {
/*
Chapéu Mexicano
*/
passo = (float)1/escala[i];
total_passo = 10/passo;
for(j=-5, k=0; j<5, k<total_passo; j+=passo,k++) {
mexh[k] = 2.1741*(1/sqrt(2*pi)*(1-pow(j,2))*exp(-pow(j,2)/(2)));
}
/*
Convolution
*/
// conv(total_passo,mexh[0],mexh,MAX_SAMPLE,data[0],data,MAX_SAMPLE+total_passo,0,convol);
//
for(k=0; k<(MAX_SAMPLE+total_passo); k++) {
if (k<MAX_SAMPLE)
aux1[k]=data[k];
else
aux1[k]=0;
if (k<total_passo)
aux2[k]=mexh[k];
else
aux2[k]=0;
}
for(l=0;l<(2500+total_passo); l++) {
convol[l]=0;
convol[l] =convol[l]+ (aux1[l] * aux2[l]);
}
//derivada de primeira ordem
for (i=1; i<MAX_SAMPLE; i++)
convol[i-1]=convol[i]-convol[i-1];
/*
Hilbert
*/
hilbert(MAX_SAMPLE+total_passo, convol [],aux1 [] );
i++;
}
return 0;
}
I´d like to implement convolution and hilbert from this lib cwplib
I try to implement convolution by this algorithm above but the results differ from Matlab.
If not, how can I implement Hilbert for another way or the convolution?
How can I do? Thanks any help.

Related

Saving numbers from file to array in C

In my code I opened file (succesful) and I am trying to get the numbers to array, but it does not working (control output is bad). Compiler did not show me any error.
link on txt file: https://textuploader.com/1amip
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE *fr_koty;
int **array = NULL;
int x = 1; /* Pocet radku */
int y = 1; /* Pocet sloupcu */
char line[1024];
char *assistant_line;
int number; /* Promena pro cislo*/
char *tab;
if((fr_koty = fopen("koty.txt", "r")) == NULL) {
printf("Soubor se nepodarilo otevrit!");
return 0;
}
while(fgets(line, 1023, fr_koty) != NULL) {
array = (int **) realloc(array, x * sizeof(int *));
array[x] = NULL;
assistant_line = line;
while(sscanf(assistant_line, "%d", &number) == 1) {
array[x] = (int *) realloc(array[x], y * sizeof(int));
array[x][y] = number;
printf("%d ", array[x][y]);
if((tab = strchr(assistant_line, '\t')) != NULL) {
assistant_line = tab + 1;
y++;
}
else {
break;
}
}
putchar('\n');
x++;
}
}
Output of numbers is random. I think the reason is bad working with memory, but I can not see the problem.
You're initializing x and y to 1, which is ok for the realloc, but as C arrays are 0 based, you need to use x-1 and y-1 to access the array elements.
Or you init them to 0 and use (x+1) and (y+1) in the realloc call. I would prefer this way.
Now I see it too. Thank you!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
FILE *fr_koty;
int **array = NULL;
int x = 1; /* Pocet radku */
int y; /* Pocet sloupcu */
char line[1024];
char *assistant_line;
int number; /* Promena pro cislo*/
char *tab;
if((fr_koty = fopen("koty.txt", "r")) == NULL) {
printf("Soubor se nepodarilo otevrit!");
return 0;
}
while(fgets(line, 1023, fr_koty) != NULL) {
y = 1;
array = (int **) realloc(array, x * sizeof(int *));
array[x-1] = NULL;
assistant_line = line;
while(sscanf(assistant_line, "%d", &number) == 1) {
array[x-1] = (int *) realloc(array[x-1], y * sizeof(int));
array[x-1][y-1] = number;
printf("%d ", array[x-1][y-1]);
if((tab = strchr(assistant_line, '\t')) != NULL) {
assistant_line = tab + 1;
y++;
}
else {
break;
}
}
putchar('\n');
x++;
}
}

Continued Power Function Message

I keep getting the error message that my I have an undefined reference to the power function, but I'm not really sure where that is occurring or why my code is coming up with that error because I have used to power function before in this way. If anyone could help me figure out why it isn't working now I would really appreciate it.
#include "stdio.h"
#include "string.h" //Needed for strlen()
#include "math.h"
#define MAX_BITS 32
#define MAX_LENGTH 49
#define NUMBER_TWO 2
#define NUMBER_ONE 1
#define TERMINATOR '\0'
//Code to find the index of where the string ends
int last_index_of(char in_str[], char ch) {
for (int i = 0; i < MAX_LENGTH; i++) {
if(in_str[i] == ch) {
last_index_of == i;
}
}
return last_index_of;
}
//Code to find the start of the fractional aspect
void sub_string(char in_str[], char out_str[], int start, int end){
int i = 0;
while (i < 1) {
out_str[i] = in_str[start] + in_str[end-1];
i++;
}
}
int main()
{
//Declaration of variable
char input[MAX_LENGTH +1]; // +1 for '\0'
int number;
double exponent;
char output[MAX_BITS];
int fraction;
sub_string(input, output, 0, TERMINATOR);
//Input from the user
printf("Enter a floating point value in binary: ");
scanf("%s", input);
//Calculates the Decimal Part
for (int i = 0; i < last_index_of(input, TERMINATOR) ; i++) {
number = number + number + input[i];
}
printf("%d", number);
exponent = -1;
//Calculates the Fractional Part
for (int j = 0; j < last_index_of(input, TERMINATOR); j++) {
if (j == last_index_of) {
fraction = NUMBER_ONE/(pow(NUMBER_TWO, exponent));
printf("%d/n", fraction);
}
else {
fraction = NUMBER_ONE/(pow(NUMBER_TWO, exponent));
printf("%d + ", fraction);
exponent--;
}
}
return 0;
}
Some problems:
you need -lm option to linker to tell it where to find pow function
last_index_of is not correctly written, you use the function name as an internal variable, you can correct it this way:
//Code to find the index of where the string ends
int last_index_of(char in_str[], char ch) {
int ret = 0;
for (int i = 0; i < MAX_LENGTH; i++) {
if(in_str[i] == ch) {
ret = i;
}
}
return ret;
}
Note that you can replace your last_index_of() function by strlen()
as pointed in comment, sub_string() is not functionnal. A corrected version could be:
//Code to find the start of the fractional aspect
void sub_string(char in_str[], char out_str[], int start, int end){
int i = 0;
while (start != end) {
/* warning, bounds are still not tested...*/
out_str[i++] = in_str[start++];
}
out_str[i] = '\0'
}
Instead of calling last_index_of() in your exist for loop condition, you should take its value to re-use it:
for (int j = 0; j < last_index_of(input, TERMINATOR); j++) {
/* Error here: will never be TRUE */
if (j == last_index_of) {
/* ... */
}
else {
/* ... */
}
}
would become:
int last_index = last_index_of(input, TERMINATOR);
for (int j = 0; j < last_index; j++) {
if (j == last_index) {
/* ... */
}
else {
/* ... */
}
}
Another problem, you use number variable without initializing it, you should write int number = 0 instead of int number;
After that, there is also a problem with your logic.
You have some idea of what you want to do, but it is not clear in your code.
It seems that you want
the user to input some string in the form 10010.100111
to split this string into two parts 10010 and 100111
to convert the first part into integer part 10010 -> 18
to convert the second part into fractional part 100111 -> 0.609...
This decomposition may lead you to write this kind of code:
#include "stdio.h"
#include "string.h"
#define MAX_BITS 32
#define MAX_LENGTH 49
//Code to find the index of where the string ends
int last_index_of(char in_str[], char ch)
{
int ret = 0;
for (int i = 0; i < MAX_LENGTH; i++) {
if (in_str[i] == ch) {
ret = i;
}
}
return ret;
}
void sub_string(char in_str[], char out_str[], int start, int end)
{
int i = 0;
while (start != end) {
/* warning, bounds are still not tested... */
out_str[i++] = in_str[start++];
}
out_str[i] = '\0';
}
void split(char *input, char *first, char *second)
{
int idx = last_index_of(input, '.');
sub_string(input, first, 0, idx);
sub_string(input, second, idx + 1, strlen(input));
}
int main()
{
//Declaration of variable
char input[MAX_LENGTH + 1]; // +1 for '\0'
char first[MAX_BITS];
char second[MAX_BITS];
/* Input from the user */
printf("Enter a floating point value in binary: ");
scanf("%s", input);
/* split integer and fractionnal parts */
split(input, first, second);
/* decode integer part */
printf("integer part:\n");
for (int i = strlen(first) - 1, j = 1; i > -1; --i, j <<= 1) {
if (first[i] == '1') {
printf("%d ", j);
}
}
/* decode frac part */
printf("\nfractionnal part:\n");
for (int i = 0; i < strlen(second); ++i) {
if (second[i] == '1') {
printf("1/%d ", 2 << i);
}
}
return 0;
}

reading a number of type double from a text file

I am still stuck on this problem, I have tried a lot of things to get it and still no success... All I am trying to do is read the number into one array and the letters into another. That way, I can call both at the same time to take a statistical analysis of the letter frequency of two books. I know how to do this for a string, but I want to only copy the input of the numbers, which are two spaces in front of the letter they represent. The code reads two files through the command prompt(argv[1] and argv[2]) and compares the two together take the root mean square(RMS) of the two as the output. Here is the code I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define NUM_LETTERS 26
int main( int argc, char *argv[] )
{
FILE *fp, *fp2;
int ch, i, counter;
double frequencysquared[NUM_LETTERS], freqone[NUM_LETTERS], freqtwo[NUM_LETTERS], average;
fp = fopen(argv[1], "r");
fp2 = fopen(argv[2], "r");
while((ch=fgetc(fp)) != EOF)
{
freqone[ch] = fgets(/*unsure*/, 22, fp);
}
while((ch=fgetc(fp2)) != EOF)
{
freqtwo[ch] = fgets(/*unsure*/, 22, fp2);
}
while(i=0; i<NUM_LETTERS; i++)
{
average += pow(( freqone[i]-freqtwo[i] ), 2);
}
average/=NUM_LETTERS;
average = sqrt(average);
printf("RMS Frequency: %lf", average);
fclose(fp);
fclose(fp2);
return 0;
}
Text file:
A 0.08030130328545595500
B 0.01404566680148545800
C 0.02309245337888202900
D 0.04680329046987134100
E 0.12475974957130967000
F 0.02262448732647651800
G 0.02092142515718645500
H 0.06495870199587520900
I 0.06832638626586488900
J 0.00118328558965393900
K 0.00796545073487383260
L 0.03678714564106335500
M 0.02553256208071077300
N 0.07071134182580297900
O 0.07759211410349403600
P 0.01653257210855475400
Q 0.00111309068179311220
R 0.06200383063640040700
S 0.06269909448568859700
T 0.09005003894146078300
U 0.02792921679195900500
V 0.00865068674018190480
W 0.02356209073861756000
X 0.00115988728703366340
Y 0.02033479628434954300
Z 0.00035933107595423293
Just do step at a time. Make the code as simple as possible. It is better to use a separate function to calculate the RMS, just because having everything in the main function can get overwhelming.
Here is some example code that will help you achieve your task:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define NUMLETTERS 26
#define RMS_VALID 1
#define RMS_INVALID 0
double calc_rms(double X[], double Y[], int n, double *rms);
void read_file(double numbers[], char letters[], FILE *stream);
int
main(int argc, char const *argv[]) {
FILE *fp1, *fp2;
double numbers1[NUMLETTERS], numbers2[NUMLETTERS];
char letters1[NUMLETTERS], letters2[NUMLETTERS];
double rms;
fp1 = fopen(argv[1], "r");
fp2 = fopen(argv[2], "r");
if (fp1 == NULL || fp2 == NULL) {
fprintf(stderr, "%s\n", "Error Reading a File");
exit(EXIT_FAILURE);
}
read_file(numbers1, letters1, fp1);
read_file(numbers2, letters2, fp2);
if (calc_rms(numbers1, numbers2, NUMLETTERS, &rms) != RMS_INVALID) {
printf("RMS Frequency: %f\n", rms);
}
return 0;
}
void
read_file(double numbers[], char letters[], FILE *stream) {
double onedouble;
char oneletter;
int count = 0;
while (fscanf(stream, " %c %lf", &oneletter, &onedouble) == 2) {
numbers[count] = onedouble;
letters[count] = oneletter;
count++;
}
}
double
calc_rms(double X[], double Y[], int n, double *rms) {
int i;
double sum = 0.0, diff;
if (n <= 0) {
return RMS_INVALID; // just for precaution
}
for (i = 0; i < n; i++) {
diff = (X[i] - Y[i]);
sum += diff * diff;
}
*rms = sqrt(sum/n);
return RMS_VALID;
}
The rough outline of the program is on the right track, but you have many details wrong. For one, scanf can take care of getting the input. No need to fiddle with strings.
Also, you need much better error checking.
Here's a start:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE ('Z' - 'A' + 1)
void die(int err) {
fprintf(stderr, "error %d\n", err);
exit(err);
}
int main(int argc, char *argv[]) {
char ch;
double f, a[SIZE], b[SIZE];
FILE *fa, *fb;
if (argc != 3) die(1);
fa = fopen(argv[1], "r");
if (!fa) die(2);
fb = fopen(argv[2], "r");
if (!fb) die(3);
for (int i = 0; i < SIZE; ++i)
a[i] = b[i] = -1.0;
while (fscanf(fa, " %c%lf", &ch, &f) == 2)
if ('A' <= ch && ch <= 'Z') a[ch - 'A'] = f; else die(4);
fclose(fa);
while (fscanf(fb, " %c%lf", &ch, &f) == 2)
if ('A' <= ch && ch <= 'Z') b[ch - 'A'] = f; else die(5);
fclose(fb);
double sum_d2 = 0;
for (int i = 0; i < SIZE; ++i) {
if (a[i] < 0 || b[i] < 0) die(100 + i);
double d = a[i] - b[i];
sum_d2 += d * d;
}
double rms = sqrt(sum_d2 / SIZE);
printf("RMS Frequency: %f\n", rms);
return 0;
}

array sorting in randomly

i have below code, that i expect should read text from file, store words in array and then print it out in random order. Final array is int, but should be char and it does not give me proper answer.
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include <time.h>
int main()
{
char message[10][150], buffer[150];
int i = 0;
int cntr = 9;
char freeArray[9];
srand(time(NULL));
freeArray[i] = rand() % cntr;
FILE *file_in;
file_in = fopen("test.txt", "r");
while (fgets(buffer, 150, file_in))
{
i = rand() % cntr;
strcpy(message[freeArray[i]], buffer);
}
while (cntr >= 0)
{
i = rand() % cntr;
strcpy(message[freeArray[i]], buffer);
freeArray[i] = freeArray[cntr--];
printf("%s", freeArray[i]);
}
return 0;
}
I have alternative code, but this one gives me text without shuffle.
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include <time.h>
int main()
{
/*declare and initialise variable*/
char message[10][150],buffer[150];
int i=0;
int j;
srand(time(NULL));
FILE *file_in;
file_in=fopen("test.txt", "r");
/*stores and prints the data from the string*/
while(fgets(buffer,150,file_in)){
strcpy(message[i],buffer);
}
while(i < 10)
{
j = rand() % 10;
printf("%s\n",message[j]);
i++;
}
return 0;
The following code:
-- compiles cleanly
-- contains all the changes needed to the OPs posted code
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define MAX_MESSAGES (10)
#define MAX_MESSAGE_LEN (150)
static char message[MAX_MESSAGES][MAX_MESSAGE_LEN] = {{'\0'}};
static char buffer[MAX_MESSAGE_LEN] = {'\0'};
int main()
{
/*declare and initialise variable*/
int i=0;
int j;
FILE *file_in;
if( NULL == (file_in=fopen("test.txt", "r") ) )
{ // then, fopen failed
perror( "fopen failed for test.txt" );
exit( EXIT_FAILURE );
}
// implied else, fopen successful
srand(time(NULL));
/*stores and prints the data from the string*/
while( (i<MAX_MESSAGES) && fgets(buffer,150,file_in) )
{
strcpy(message[i],buffer);
i++;
} // end while
printf("\ndisplay %d messages in random order\n", MAX_MESSAGES);
printf("with possible repeated messages and skipped messages\n");
for( i=0; i < MAX_MESSAGES; i++)
{
j = rand() % MAX_MESSAGES;
printf("message: %d: %s\n",j, message[j]);
} // end for
return 0;
} // end function: main
The following is to answer the question given in an answer block
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#include <time.h>
#define MAX_MESSAGES (10)
#define MAX_MESSAGE_LEN (150)
static char message[MAX_MESSAGES][MAX_MESSAGE_LEN] = {{'\0'}};
static char buffer[MAX_MESSAGE_LEN] = {'\0'};
static char t[MAX_MESSAGE_LEN] = {'\0'};
int main()
{
/*declare and initialise variable*/
int i=0;
int j = 0;
FILE *file_in = NULL;
if( NULL == (file_in=fopen("test.txt", "r") ) )
{ // then, fopen failed
perror("fopen for test.txt failed");
exit( EXIT_FAILURE );
}
// implied else, fopen successful
/*stores, sorts and prints the data from the string*/
i = 0;
while( (i<10) && (fgets(buffer,150,file_in)) )
{
strcpy(message[i],buffer);
i++;
} // end while
for (i = 1; i < 3; i++)
{
for (j = 1; j < 3; j++)
{
if (strcmp(message[j - 1], message[j]) > 0)
{
strcpy(t, message[j - 1]);
strcpy(message[j - 1], message[j]);
strcpy(message[j], t);
} // end if
} // end for
} // end for
printf("\nStrings in order are : ");
for (i = 0; i < 3; i++)
{
printf("message: %d: %s\n", i+1, message[j]);
} // end for
getchar();
return 0;
} // end function: main

Calculating entropy in C

I'm trying to find the entropy of any given file. However, when I run my program, it always gives 3.00000 as an answer. I haven't used C in awhile, but I'm not sure where I'm going wrong here. I've been fiddling with it for a few hours now. Any tips would be great, thank you!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#define SIZE 256
int entropy_calc(long byte_count[], int length)
{
float entropy;
float count;
int i;
/* entropy calculation */
for (i = 0; i < SIZE; i++)
{
if (byte_count[i] != 0)
{
count = (float) byte_count[i] / (float) length;
entropy += -count * log2f(count);
}
}
return entropy;
}
int main(int argc, char **argv)
{
FILE *inFile;
int i;
int j;
int n; // Bytes read by fread;
int length; // length of file
float count;
float entropy;
long byte_count[SIZE];
unsigned char buffer[1024];
/* do this for all files */
for(j = 1; j < argc; j++)
{
memset(byte_count, 0, sizeof(long) * SIZE);
inFile = fopen(argv[j], "rb"); // opens the file given on command line
if(inFile == NULL) // error-checking to see if file exists
{
printf("Files does not exist. `%s`\n", argv[j]);
continue;
}
/* Read the whole file in parts of 1024 */
while((n = fread(buffer, 1, 1024, inFile)) != 0)
{
/* Add the buffer to the byte_count */
for (i = 0; i < n; i++)
{
byte_count[(int) buffer[i]]++;
length++;
}
}
fclose(inFile);
float entropy = entropy_calc(byte_count, length);
printf("%02.5f \t%s\n", entropy, argv[j]);
}
return 0;
}
Your return type of the function entropy_calc() should be float not int.

Resources