Invalid operands in sigmoid function - c

I am working on a Neural Network, and when trying to do the sigmoid function, it shows an error which I do not understand: invalid operands to binary ^ (have 'double' and 'int'). Here's my piece of code:
double neuron(const int num_in, const double input[num_in], const double weight[num_in], const double bias) {
int i;
int asubj = 0;
int zsubj;
for (i = 0; i < num_in; i++)
{
asubj = asubj + input[i]*weight[i]+bias;
}
zsubj = (1)/(1 - (int)(M_E)^(-asubj)); // When I run the program, it stops here, I don
return 0;
}
Any help would be much appreciated.

As noted elsewhere ^ is exclusive-or operator in C. The following might do what you want a little better:
double neuron(const int num_in,
const double input[num_in],
const double weight[num_in],
const double bias)
{
int i;
double asubj = 0.0;
double zsubj;
for (i = 0; i < num_in; i++)
asubj = asubj + input[i]*weight[i]+bias;
zsubj = 1.0 / (1.0 - pow(M_E, -asubj));
return 0;
}
Note that the code above retains the return 0; at the end shown in the original function.

Related

(book example) Why is char* argv[argc+1] returning an error?

I'm trying to learn C through the book Modern C by Jens Gustedt. In it is the following example
#include <stdlib.h>
#include <stdio.h>
/* lower and upper iteration limits centered around 1.0 */
static double const eps1m01 = 1.0 - 0x1P-01;
static double const eps1p01 = 1.0 + 0x1P-01;
static double const eps1m24 = 1.0 - 0x1P-24;
static double const eps1p24 = 1.0 + 0x1P-24;
int main (int argc, char* argv[argc+1]) {
for (int i = 1; i < argc; ++i) { // process args
double const a = strtod(argv[i], 0); // arg -> double
double x = 1.0;
for (;;) { // by powers of 2
double prod = a * x;
if (prod < eps1m01) {
x *= 2.0;
}
else if (eps1p01 < prod) {
x *= 0.5;
}
else {
break;
}
}
printf("x: %f \n", x);
for (;;) { // Heron approximation
double prod = a * x;
if ((prod < eps1m24) || (eps1p24 < prod)) {
x *= (2.0 - prod);
}
else {
break;
}
}
printf("heron: a = % .5e, \tx = % .5e, \ta * x = % .12f\n",
a, x, a * x);
}
return EXIT_SUCCESS;
}
I'm using visual studio to follow along and this
char* argv[argc+1]
gives me an error at argc+1, I removed it and it seems to work, but I'd like to know if this is in anyway changing what the program does/ if this is just an antiquated way of writing the argument
int main (int argc, char* argv[argc+1]) declares the argv parameter as a variable length array (VLA).
Variable length arrays are an optional feature of C. Compilers don't have to support it. MSVC does not support it. Other major compilers do.
This declaration of main does not conform to the standard at all. The standard allows two forms of main:
int main(int argc, char* argv[]) // note no size in brackets
int main(void)
Other functions can have VLA arguments but main cannot.
So it is an error in the book. Remove the size between the brackets and all should be well.

Pointers to structs, C

I have these two structs, everything goes well, but when I try calculating poly->scope
The output is 0.0 , like nothing really happens.
Also, I get some errors I cannot understand, for example -
the line scanPoint(&poly->points[i]); says "Dereferencing NULL pointer"
Thanks for help.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct point
{
int x, y;
}point;
typedef struct polygon
{
int n;
point* points;
double scope;
}polygon;
void scanPoint(point*);
void scanPolygon(polygon*);
double distance(point*, point*);
void calculatePolygonScope(polygon*);
void freeMemory(polygon*);
int main()
{
polygon poly;
scanPolygon(&poly);
calculatePolygonScope(&poly);
freeMemory(&poly);
printf("Output: Scope of polygon: %.2lf\n", poly.scope);
return 0;
}
void scanPoint(point* p)
{
printf("Please Enter X of your point: \n");
scanf("%d", &p->x);
printf("Please Enter Y of your point: \n");
scanf("%d", &p->y);
}
void scanPolygon(polygon* poly)
{
int i;
printf("Please enter how many points does the polygon have? : \n");
scanf("%d", &poly->n);
poly->points = (point*)calloc(poly->n, sizeof(point));
for (i = 0; i < poly->n; i++)
{
scanPoint(&poly->points[i]);
}
}
double distance(point* p1, point* p2)
{
double x = pow(((double)p2->x - (double)p1->x), 2);
double y = pow(((double)p2->y - (double)p1->y), 2);
double dis = sqrt(x + y);
return dis;
}
void calculatePolygonScope(polygon* poly)
{
int i;
double temp = 0.0;
for (i = 0; i < poly->n-1;)
{
temp += distance(&poly->points[i], &poly->points[++i]);
}
poly->scope = temp;
}
void freeMemory(polygon* poly)
{
free(poly->points);
}
The function call distance(&poly->points[i], &poly->points[++i]); in calculatePolygonScope exhibits undefined behavior because it uses the value of i in two places, one of which modifies the value of i. From C17 6.5/2:
If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.85)
85)This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a[i] = i;
To fix it, do the increment of i in the for loop control:
for (i = 0; i < poly->n-1; i++)
{
temp += distance(&poly->points[i], &poly->points[i + 1]);
}
If calculatePolygonScope is supposed to calculate the perimeter of the polygon, it is missing the edge between the first and last points. It could be changed as follows to include that edge:
void calculatePolygonScope(polygon* poly)
{
int i;
double temp = 0.0;
for (i = 0; i < poly->n-1; i++)
{
temp += distance(&poly->points[i], &poly->points[i + 1]);
}
if (poly->n > 1)
{
/* Last edge */
temp += distance(&poly->points[poly->n-1], &poly->points[0]);
}
poly->scope = temp;
}
As an aside, the distance function can be simplified by using the hypot function:
double distance(point* p1, point* p2)
{
return hypot(p2->x - p1->x, p2->y - p1->y);
}
or to avoid any possible integer overflow:
double distance(point* p1, point* p2)
{
return hypot((double)p2->x - p1->x, (double)p2->y - p1->y);
}
EDIT: OP is not allowed to use hypot, but the distance function can still be simplified by using simple multiplication to do the squaring, instead of using the more expensive (and potentially less accurate) pow function:
double distance(point* p1, point* p2)
{
double x = (double)p2->x - (double)p1->x;
double y = (double)p2->y - (double)p1->y;
double dis = sqrt(x * x + y * y);
return dis;
}
Note: It is not actually necessary to cast both operands of the subtraction operator to double. The other can be left as an int and will be converted to double automatically before the subtraction is performed.
You probably want this:
void calculatePolygonScope(polygon* poly)
{
int i;
double temp = 0.0;
for (i = 0; i < poly->n - 1; i++)
{
temp += distance(&poly->points[i], &poly->points[i + 1]);
}
poly->scope = temp;
}
With that modification the function returns the sum the polygon's segments except the last segment.
If the function is supposed to return the perimeter of the polygon, you need obviously to add another modification. I let you findout yourself how to do this as an exercise.

Hi, I have trouble using pointers

This C code works fine in Codeblocks but not in other environments. I think Codeblocks automatically uses pointer and modifies the code
return (Result){sum, mean, var}; << This part has an error in visual studio.
error C4576: a parenthesized type followed by an initializer list is a non-standard explicit type conversion syntax
Would there be any suggestion that can fix the code to use pointers? Thank you for reading my question!
#include<stdio.h>
#define SIZE 6
typedef struct Result {
float sum, mean, variance;
}Result;
Result Statistics(int a[]);
int main()
{
int array[SIZE] = { 1,2,3,4,5,6 };
Result result;
result = Statistics(array);
printf("Sum=%.2f\n", result.sum);
printf("Mean=%.2f\n", result.mean);
printf("Variance=%.2f\n", result.variance);
return 0;
}
Result Statistics(int a[])
{
float sum, mean, var, sum2, diff;
int i;
for (sum = 0, i = 0; i < SIZE; i++) {
sum += (float)a[i];
}
mean = sum / SIZE;
for (sum2 = 0, i = 0; i < SIZE; i++) {
diff = (float)a[i] - mean;
sum2 += diff * diff;
}
var = sum2 / SIZE;
return (Result){sum, mean, var};
}
Your compiler does not support standard C. Change
return (Result){sum, mean, var};
to:
{
Result temp = {sum, mean, var};
return temp;
}

Segfault with large int - not enough memory?

I am fairly new to C and how arrays and memory allocation works. I'm solving a very simple function right now, vector_average(), which computes the mean value between two successive array entries, i.e., the average between (i) and (i + 1). This average function is the following:
void
vector_average(double *cc, double *nc, int n)
{
//#pragma omp parallel for
double tbeg ;
double tend ;
tbeg = Wtime() ;
for (int i = 0; i < n; i++) {
cc[i] = .5 * (nc[i] + nc[i+1]);
}
tend = Wtime() ;
printf("vector_average() took %g seconds\n", tend - tbeg);
}
My goal is to set int n extremely high, to the point where it actually takes some time to complete this loop (hence, why I am tracking wall time in this code). I'm passing this function a random test function of x, f(x) = sin(x) + 1/3 * sin(3 x), denoted in this code as x_nc, in main() in the following form:
int
main(int argc, char **argv)
{
int N = 1.E6;
double x_nc[N+1];
double dx = 2. * M_PI / N;
for (int i = 0; i <= N; i++) {
double x = i * dx;
x_nc[i] = sin(x) + 1./3. * sin(3.*x);
}
double x_cc[N];
vector_average(x_cc, x_nc, N);
}
But my problem here is that if I set int N any higher than 1.E5, it segfaults. Please provide any suggestions for how I might set N much higher. Perhaps I have to do something with malloc, but, again, I am new to all of this stuff and I'm not quite sure how I would implement this.
-CJW
A function only has 1M stack memory on Windows or other system. Obviously, the size of temporary variable 'x_nc' is bigger than 1M. So, you should use heap to save data of x_nc:
int
main(int argc, char **argv)
{
int N = 1.E6;
double* x_nc = (double*)malloc(sizeof(dounble)*(N+1));
double dx = 2. * M_PI / N;
for (int i = 0; i <= N; i++) {
double x = i * dx;
x_nc[i] = sin(x) + 1./3. * sin(3.*x);
}
double* x_cc = (double*)malloc(sizeof(double)*N);
vector_average(x_cc, x_nc, N);
free(x_nc);
free(x_cc);
return 0;
}

Selecting and analysing window of points in an array

Could someone please advise me on how to resolve this problem.
I have a function which performs a simple regression analysis on a sets of point contained in an array.
I have one array (pval) which contains all the data I want to perform regression analysis on.
This is how I want to implement this.
I get an average value for the first 7 elements of the array. This is what I call a 'ref_avg' in the programme.
I want to perform a regression analysis for every five elements of the array taking the first element of this array as the 'ref_avg'. That is in every step of the regression analysis I will have 6 points in the array.
e.g
For the 1st step the ref_avg as calculated below is 70.78. So the 1st step in the simple regression will contain these points
1st = {70.78,76.26,69.17,68.68,71.49,73.08},
The second step will contain the ref_avg as the 1st element and other elements starting from the second element in the original array
2nd = {70.78,69.17,68.68,71.49,73.08,72.99},
3rd = {70.78,68.68,71.49,73.08,72.99,70.36},
4th = {70.78,71.49,73.08,72.99,70.36,57.82} and so on until the end.
The regression function is also shown below.
I don't understand why the first 3 elements of the 'calcul' array have value 0.00 on the first step of the regression, 2 elements on the 2nd step,1 elements on the 3rd.
Also the last step of the regression function is printed 3 times.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
float pval[]={76.26,69.17,68.68,71.49,73.08,72.99,70.36,57.82,58.98,69.71,70.43,77.53,80.77,70.30,70.5,70.79,75.58,76.88,80.20,77.69,80.80,70.5,85.27,75.25};
int count,Nhour;
const int MAX_HOUR = 24;
float *calcul=NULL;
float *tab_time =NULL;
float ref_avg;
int size_hour=7;
float sum=0;
int length = Nhour+1;
float m;
float b;
calcul=(float*)calloc(MAX_HOUR,sizeof(calcul));
if (calcul==NULL)
{
printf(" error in buffer\n");
exit(EXIT_FAILURE);
}
tab_time= calloc(MAX_HOUR,sizeof(float));
/* Get the average of the first seven elements */
int i;
for (i=0;i<size_hour;i++)
{
sum += pval[i];
}
ref_avg = sum / size_hour;
count=0;
/* perform the regression analysis on 5 hours increment */
while(count<=MAX_HOUR)
{
++count;
Nhour=5;
int pass = -(Nhour-1);
int i=0;
for(i=0;i<Nhour+1;i++)
{
if(count<MAX_HOUR)
{
calcul[0]=ref_avg;
calcul[i] =pval[count+pass];
pass++;
}
printf("calc=%.2f\n",calcul[i]); // For debug only
tab_time[i]=i+1;
if(i==Nhour)
{
linear_regression(tab_time, calcul, length, &m, &b);
printf("Slope= %.2f\n", m);
}
}
}
free(calcul);
calcul=NULL;
free(tab_time);
tab_time=NULL;
return 0;
}
/* end of the main function */
/* This function is used to calculate the linear
regression as it was called above in the main function.
It compiles and runs very well, was just included for the
compilation and execution of the main function above where I have a problem. */
int linear_regression(const float *x, const float *y, const int n, float *beta1, float *beta0)
{
float sumx = 0,
sumy = 0,
sumx2 = 0,
sumxy = 0;
int i;
if (n <= 1) {
*beta1 = 0;
*beta0= 0;
printf("Not enough data for regression \n");
}
else
{
float variance;
for (i = 0; i < n; i++)
{
sumx += x[i];
sumy += y[i];
sumx2 += (x[i] * x[i]);
sumxy += (x[i] * y[i]);
}
variance = (sumx2 - ((sumx * sumx) / n));
if ( variance != 0) {
*beta1 = (sumxy - ((sumx * sumy) / n)) / variance;
*beta0 = (sumy - ((*beta1) * sumx)) / n;
}
else
{
*beta1 = 0;
*beta0 = 0;
}
}
return 0;
}
I think this code produces sane answers. The reference average quoted in the question seems to be wrong. The memory allocation is not needed. The value of MAX_HOUR was 24 but there were only 23 data values in the array. The indexing in building up the array to be regressed was bogus, referencing negative indexes in the pval array (and hence leading to erroneous results). The variable Nhour was referenced before it was initialized; the variable length was not correctly set. There wasn't good diagnostic printing.
The body of main() here is substantially rewritten; the editing on linear_regression() is much more nearly minimal. The code is more consistently laid out and white space has been used to make it easier to read. This version terminates the regression when there is no longer enough data left to fill the array with 5 values - it is not clear what the intended termination condition was.
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void linear_regression(const float *x, const float *y, const int n,
float *beta1, float *beta0);
int main(void)
{
float pval[]={
76.26, 68.68, 71.49, 73.08, 72.99, 70.36, 57.82, 58.98,
69.71, 70.43, 77.53, 80.77, 70.30, 70.50, 70.79, 75.58,
76.88, 80.20, 77.69, 80.80, 70.50, 85.27, 75.25,
};
const int Nhour = 5;
const int MAX_HOUR = sizeof(pval)/sizeof(pval[0]);
const int size_hour = 7;
float ref_avg;
float sum = 0.0;
float m;
float b;
float calc_y[6];
float calc_x[6];
/* Get the average of the first seven elements */
for (int i = 0; i < size_hour; i++)
sum += pval[i];
ref_avg = sum / size_hour;
printf("ref avg = %5.2f\n", ref_avg); // JL
/* perform the regression analysis on 5 hours increment */
for (int pass = 0; pass <= MAX_HOUR - Nhour; pass++) // JL
{
calc_y[0] = ref_avg;
calc_x[0] = pass + 1;
printf("pass %d\ncalc_y[0] = %5.2f, calc_x[0] = %5.2f\n",
pass, calc_y[0], calc_x[0]);
for (int i = 1; i <= Nhour; i++)
{
int n = pass + i - 1;
calc_y[i] = pval[n];
calc_x[i] = pass + i + 1;
printf("calc_y[%d] = %5.2f, calc_x[%d] = %5.2f, n = %2d\n",
i, calc_y[i], i, calc_x[i], n);
}
linear_regression(calc_x, calc_y, Nhour+1, &m, &b);
printf("Slope= %5.2f, intercept = %5.2f\n", m, b);
}
return 0;
}
void linear_regression(const float *x, const float *y, const int n, float *beta1, float *beta0)
{
float sumx1 = 0.0;
float sumy1 = 0.0;
float sumx2 = 0.0;
float sumxy = 0.0;
assert(n > 1);
for (int i = 0; i < n; i++)
{
sumx1 += x[i];
sumy1 += y[i];
sumx2 += (x[i] * x[i]);
sumxy += (x[i] * y[i]);
}
float variance = (sumx2 - ((sumx1 * sumx1) / n));
if (variance != 0.0)
{
*beta1 = (sumxy - ((sumx1 * sumy1) / n)) / variance;
*beta0 = (sumy1 - ((*beta1) * sumx1)) / n;
}
else
{
*beta1 = 0.0;
*beta0 = 0.0;
}
}

Resources