Trying to implement a perceptron in C, can't get it to train.
The output always just goes to zero and I don't know what’s wrong.
Although, I do suspect it might be either the delta function or me just incorrectly implementing the perceptron.
Thanks in advance to everyone who helps!
#include<stdio.h>
#define arrayLength(x) (sizeof(x) / sizeof((x)[0]))
typedef int bool;
enum { false, true };
int main(){
float trainInputs [2][2] = {{0.0f, 1.0f}, {0.0f, 0.0f}};
float trainOutputs [2][1] = {{1.0f}, {0.0f}};
int amontOfTrainData = 1;
float inputs [] = {0.0f, 1.1f};
float outputs [] = {0.0f};
float wights [(arrayLength(inputs) * arrayLength(outputs))] = {0.5f, 0.5f, 0.5f, 0.5f};
float learningRate = 0.01f;
float delta(float actual, float want, float wight){
float error = want - actual;
float out = error * learningRate * wight;
printf(":%.6f:\n", out);
return out;
}
// Run perceptron
void run(bool train){
int outputInc = 0;
int wightInc = 0;
while(outputInc < arrayLength(outputs)){
int inputInc = 0;
while(inputInc < arrayLength(inputs)){
if(train){
int x = 0;
while(x < amontOfTrainData){
outputs[outputInc] = trainInputs[x][inputInc] * wights[wightInc];
wights[wightInc] = delta(outputs[outputInc], trainOutputs[x][outputInc], wights[wightInc]);
x++;
}
}else{
outputs[outputInc] = inputs[inputInc] * wights[wightInc];
}
inputInc++;
wightInc++;
}
//printf("out[%i]: %.5f\n", outputInc, outputs[outputInc]);
outputInc++;
}
}
int b = 0;
while(b < 100){
run(true);
b++;
}
printf("-----------[ 100 LOOPS DONE ]-----------\n");
run(false);
return 0;
}
As error, learningRate and wight are less than 0, the expression error * learningRate * wight will tend to 0 too.
The delta should not be the new value for the weight, it is the amount of change, so instead of:
wights[wightInc] = delta(...);
Try:
wights[wightInc] += delta(...);
(Which source are you using for you perceptron formulas?)
I have applied all the changes and this is the final working code.
Thanks to everyone who helped me!
#include<stdio.h>
#include<stdbool.h>
#define arrayLength(x) (sizeof(x) / sizeof((x)[0]))
float trainInputs [2][2] = {{0.0f, 1.0f}, {0.0f, 0.0f}};
float trainOutputs [2][1] = {{1.0f}, {0.0f}};
int amontOfTrainData = 1;
float inputs [] = {1.0f, 1.0f};
float outputs [] = {0.0f};
float wights [(arrayLength(inputs) * arrayLength(outputs))] = {0.001f, 0.001f};
float learningRate = 0.1f;
float delta(float actual, float want, float wight)
{
float error = want - actual;
float out = error * learningRate * wight;
return out;
}
void run(bool train)
{
int outputInc = 0;
int wightInc = 0;
while(outputInc < arrayLength(outputs))
{
int inputInc = 0;
while(inputInc < arrayLength(inputs))
{
if(train)
{
int x = 0;
while(x < amontOfTrainData)
{
outputs[outputInc] = trainInputs[x][inputInc] * wights[wightInc];
wights[wightInc] += delta(outputs[outputInc], trainOutputs[x][outputInc], wights[wightInc]);
x++;
}
}
else
{
outputs[outputInc] = inputs[inputInc] * wights[wightInc];
}
inputInc++;
wightInc++;
}
printf("out[%i]: %.5f\n", outputInc, outputs[outputInc]);
outputInc++;
}
}
int main()
{
// Run neural network
int b = 0;
int loops = 500;
while(b < loops)
{
run(true);
b++;
}
printf("-----------[ %i LOOPS DONE ]-----------\n", loops);
run(false);
return 0;
}
Related
I can't find and resolve the error in this code.
I want Parray and Tarray to be filled with an iteration of the equation in the loop. I tried both for and while loop, but it seems that only the first member of the array is given proper value, and that value is lost by the beginning of a new cycle.
#include <stdio.h>
#include <stdlib.h>
int main() {
int i;
int j;
float dt,P_init,t_init,t_end;
dt = 0.03125;
P_init = 30;
t_init = 0;
t_end = 30;
int n_steps = 0;
n_steps = t_end/(float)dt;
int Parray[n_steps+1];
int Tarray[n_steps+1];
for (i=0; i<n_steps+1; i++)
{
Parray[i]=0;
Tarray[i]=0;
}
Parray[0] = P_init;
Tarray[0] = t_init;
int x;
float P,t,dpdt;
x = 1;
while (x < n_steps+1)
{
float s,d;
P = Parray[x-1];
t = Tarray[x-1];
dpdt = 0.7 * P * (1-(P/750)) - 20;
s = P + (dt * dpdt);
Parray[x] = s;
d = t + dt;
Tarray[x] = d;
x++;
printf("%f %f ",s,d);
}
return(0);
}
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int i, j, x;
float dt, P_init, t_init, t_end, P, t, dpdt;
dt = 0.03125;
P_init = 30;
t_init = 0;
t_end = 30;
int n_steps = 0;
n_steps = t_end / (float)dt;
// using float arrays
float Parray[n_steps+1];
float Tarray[n_steps+1];
for (i = 0; i < n_steps+1; i++)
Parray[i] = 0;
for (j = 0; j < n_steps+1; j++)
Tarray[j] = 0;
Parray[0] = P_init;
Tarray[0] = t_init;
for (x = 1; x < n_steps + 1; x++) {
float s , d;
P = Parray[x-1];
t = Tarray[x-1];
dpdt = 0.7 * P * (1 - (P / 750)) - 20;
s = P + (dt * dpdt);
Parray[x] = s;
d = t + dt;
Tarray[x] = d;
printf("%f %f\n", s, d);
}
return(0);
}
I changed the int arrarys to float arrays.
What do you actually calculate here?
This line
dpdt = 0.7 * P * (1-(P/750)) - 20;
It seems to have a float value, therefore the array must be float type, and ALL inputs you put in the array must be in FLOAT type.
Change this:
int Parray[n_steps+1];
int Tarray[n_steps+1];
to
float Parray[n_steps+1];
float Tarray[n_steps+1];
and
P_init = 30;
t_init = 0;
t_end = 30;
All of them should be 30.0, 0.0, 30.0
Don't forget this too:
Parray[i]=0;
Tarray[i]=0;
Change it to 0.0
In short, C is bad at differentiate between types, so if you declare a float array, all inputs must be x.0, not only x where x is an integer.
I am trying to translate the Automatic Gain Control block from Matlab's communications toolbox. Here is the documentation but the relevant parts are summarized below:
The block diagram
Where
And
This is the code I've written:
double AGC_Detector(int N, float complex* input, int ndx)
{
double samp = 0;
for(int i = ndx*N; i < (ndx+1)*(N-1); i++)
{
samp += cabs(input[i])*cabs(input[i]);
}
samp = samp/N;
return samp;
}
void use_AGC(float complex* input,
float complex* output,
double step,
double desired_pwr,
int avrg_len,
int max_pwr,
int len)
{
double z = 0;
double e = 0;
double g = 0;
double prev_g = 0;
double dtctr = 0;
for(int i = 0; i < len; i++)
{
dtctr = AGC_Detector(avrg_len,input,i);
z = dtctr * exp(2*prev_g);
e = desired_pwr - log(z);
g = prev_g + step*e;
if(g > max_pwr)
{
g = max_pwr;
}
prev_g = g;
output[i] = input[i] * exp(prev_g);
}
}
But I am not getting the same output I get for the same values in Matlab. What am I doing wrong?
Thank You!
Maybe it's not the only error but I've noticed, that the sum of the AGC Detector goes from ndx*N to (ndx+1)N-1 in the Matlab documentation, but in your C code it goes from
ndx*N to (ndx+1)(N-1)
I figured it out. Code below gives same output as matlab for a given set of complex data.
double AGC_Detector(double complex input, double* sum, double state[], unsigned int* idx, int N)
{
unsigned int first;
unsigned int nth;
double output;
double val = cabs(input)*cabs(input);
*sum += val;
output = (*sum)*(1.0/N);
*sum -= state[*idx-1];
if(*sum < 0.0){*sum = 0.0;}
state[*idx-1] = val;
first = *idx;
nth = first + 1;
if(nth < first){nth = 0xFFFFFFFF;}
*idx = nth;
if(*idx > N-1){*idx = 1;}
return output;
}
void use_AGC(double complex* input, double complex* output, double step, double desired_pwr, int avrg_len, int max_pwr, int len)
{
unsigned int idx = 1;
int filt_len = avrg_len-1;
double K = step;
double g = 0;
double sum = 0;
double dtctr = 0;
double filterState[filt_len];
for(int i = 0; i < filt_len; i++){filterState[i] = 0;}
for(int i = 0; i < avrg_len; i++)
{
dtctr = AGC_Detector(input[i], &sum, filterState, &idx, avrg_len);
output[i] = input[i] * exp(g);
dtctr = log(dtctr);
g += K*(desired_pwr - (dtctr + 2.0*g));
if(g > max_pwr){g = max_pwr;}
}
}
I'm trying to parallelize my code, but i got errors. I need to calc a Cauchy problem (it's already done) but than i need to parallelize it using OpenMP lib.
I've tried to write some code with OpenMP, but it's not working.
I've created a struct to collect result.
struct Dots {
double par;
double x;
double y;
};
This is my target function with parameter.
int ode_func (double x, const double y[], double f[], void *params)
{
double mu = *(int *)params;
f[0] = x + 2 * y[0] / (1 + mu * mu);
return GSL_SUCCESS;
}
This is the main function. I currently didn't find a way how to create a array of arrays of struct, but this is not the main problem.
void calc_cauchy_problem(struct Dots ArrayOfDots[], double x_start, double x_end, double y_start,
int count) {
int dim = 1;
double x = x_start;
double y[1] = {y_start};
int mu = 5;
int param = 0;
gsl_odeiv2_system sys = {ode_func, NULL, dim, ¶m};
gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new (&sys,
gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
int status = 0;
#pragma omp parallel for shared(ArrayOfDots) private(sys, param, d, status)
for (int param = 1; param < mu; param++) {
gsl_odeiv2_system sys = {ode_func, NULL, dim, ¶m};
gsl_odeiv2_driver * d = gsl_odeiv2_driver_alloc_y_new (&sys,
gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
for (int i = 1; i <= count; i++)
{
double xi = x_start + i * (x_end - x_start) / count;
int status = gsl_odeiv2_driver_apply(d, &x, xi, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
// ArrayOfDots[i].par = mu;
// ArrayOfDots[i].x = xi;
// ArrayOfDots[i].y = y[0];
}
gsl_odeiv2_driver_free (d);
}
}
The main
int main() {
double x_start = 0;
double x_end = 10;
double y_start = 0;
int count = 10;
struct Dots ArrayOfDots[count];
calc_cauchy_problem(ArrayOfDots, x_start, x_end, y_start, count);
return 0;
}
It's compiled successfully with this gcc main.c -o main -fopenmp -lgsl -std=gnu11 but when i launch it i got error
gsl: driver.c:354: ERROR: integration limits and/or step direction not consistent
Default GSL error handler invoked.
I think that the main problem with this #pragma omp parallel for shared(ArrayOfDots) private(sys, param, d, status) but i have no idea how to rewrite this in the other way.
Thanks for your responses.
UPD:
With Kaveh Vahedipour help my code partially start to work. It means that half of my for cycle start to work.
UPD UPD:
After another investigations i had the following code:
It's compile and run, but i got Process finished with exit code 4 and printf("Elapsed time = %f\n", omp_get_wtime() - start_time); don't print anything.
struct Dots {
double par;
double x;
double y;
};
int ode_func (double x, const double y[], double f[], void *params)
{
double mu = *(int *)params;
f[0] = (x + 2 * y[0]) / (1 + mu * mu);
return GSL_SUCCESS;
}
void calc_cauchy_problem(double x_start, double x_end, double y_start,
int count, int param1, int param2) {
int dim = 1;
double x = x_start;
double y[1] = {y_start};
int param = param1;
int j = 0;
int status = 0;
char filename[10];
#pragma omp parallel for private(param, status, x, y)
for (param = param1; param <= param2; param++) {
struct Dots ArrayOfDots[count];
gsl_odeiv2_system sys = {ode_func, NULL, dim, ¶m};
gsl_odeiv2_driver * d =
gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
for (int i = 1; i <= count; i++) {
double xi = x_start + i * (x_end - x_start) / count;
int status = gsl_odeiv2_driver_apply(d, &x, xi, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
ArrayOfDots[i].par = param;
ArrayOfDots[i].x = xi;
ArrayOfDots[i].y = y[0];
}
gsl_odeiv2_driver_free (d);
}
}
int main() {
double start_time = omp_get_wtime();
double x_start = 0;
double x_end = 10;
double y_start = 0;
const int count = 500;
int param1 = 1;
int param2 = 10;
calc_cauchy_problem(x_start, x_end, y_start, count, param1, param2);
printf("Elapsed time = %f\n", omp_get_wtime() - start_time);
return 0;
}
Add x to private loop vars: private(sys, param, d, status, x). Please get back to me, if you still experience issues.
void calc_cauchy_problem(double x_start, double x_end, double y_start,
int count, int param1, int param2) {
int dim = 1;
double x = x_start;
double y[1] = {y_start};
int param = param1;
int j = 0;
int status = 0;
char filename[10];
#pragma omp parallel for private(param, status, x, y)
for (param = param1; param <= param2; param++) {
struct Dots ArrayOfDots[count];
gsl_odeiv2_system sys = {ode_func, NULL, dim, ¶m};
gsl_odeiv2_driver * d =
gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rkf45, 1e-6, 1e-6, 0.0);
for (int i = 1; i <= count; i++) {
double xi = x_start + i * (x_end - x_start) / count;
int status = gsl_odeiv2_driver_apply(d, &x, xi, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
ArrayOfDots[i].par = param;
ArrayOfDots[i].x = xi;
ArrayOfDots[i].y = y[0];
}
//write_data_to_file(param, count, ArrayOfDots);
for (int i = 0; i < count; ++i) {
printf ("%d: %f, %f, %f\n", omp_get_thread_num(),
ArrayOfDots[i].par, ArrayOfDots[i].x, ArrayOfDots[i].y);
}
gsl_odeiv2_driver_free (d);
}
}
Seems like this version works fine. I think problem was with this struct Dots ArrayOfDots[count]; and when i try to push values to this struct.
ArrayOfDots[i].par = param;
ArrayOfDots[i].x = xi;
ArrayOfDots[i].y = y[0];
Here is the full code.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
// GSL lib includes
#include <gsl/gsl_sf_bessel.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_odeiv2.h>
int ode_func (double x, const double y[], double f[], void *params)
{
double mu = *(int *)params;
f[0] = (x + 2 * y[0]) / (1 + mu * mu);
return GSL_SUCCESS;
}
void calc_cauchy_problem(double x_start, double x_end, double y_start,
int count, int param1, int param2) {
#pragma omp parallel for
for(int param = param1; param < param2; param++) {
gsl_odeiv2_system sys = {ode_func, NULL, 1, ¶m};
gsl_odeiv2_driver * d =
gsl_odeiv2_driver_alloc_y_new (&sys, gsl_odeiv2_step_rk8pd,
1e-6, 1e-6, 0.0);
int i;
double x = x_start, x1 = x_end;
double y[1] = { y_start };
for (i = 1; i <= count; i++)
{
double xi = i * x1 / count;
int status = gsl_odeiv2_driver_apply (d, &x, xi, y);
if (status != GSL_SUCCESS)
{
printf ("error, return value=%d\n", status);
break;
}
// printf ("%d %d %.5e %.5e\n", omp_get_thread_num(), param, x, y[0]);
}
gsl_odeiv2_driver_free (d);
}
}
int main() {
double start_time = omp_get_wtime();
double x_start = 0;
double x_end = 10;
double y_start = 0;
const int count = 100000;
int param1 = 1;
int param2 = 20;
calc_cauchy_problem(x_start, x_end, y_start, count, param1, param2);
printf("Elapsed time = %f\n", omp_get_wtime() - start_time);
return 0;
}
Really thanks to Kaveh Vahedipour.
I'm trying to filter my data to get rid of some noise, and I found that when I to run the filter the data from the original array with the pre-filtered data and the second array with the filtered data both become unprintable.
This is where I called the filter function(s):
int main(void)
{
int n = 0;
double sum=0.0;
USART1_Config();
ADC1_Init();
IIR_Reset();
while(1)
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC1)==SET)
{
sgolayfilt();
IIR_filter();
for(i=0;i<256;i++)
{
Send_int_Data[i]=(int)(Send_float_Data[i]*1000);
printf("%d\n",ADC_ConvertedValue[i]);
//printf("%d\n",Send_int_Data[i]);
}
DMA_ClearFlag(DMA1_FLAG_TC1);
}
}
}
This is for sgolayfilt, the function that messes up the data(I even tried printing the pre-filter array right after I called the function, but even that didn't give me any values):
float sqr(float x) {
return x*x;
}
int linreg(int n, float x[], float y[], float* m, float* b, float* r){
float sumx = 0.0;
float sumx2 = 0.0;
float sumxy = 0.0;
float sumy = 0.0;
float sumy2 = 0.0;
float denom;
for (i=0;i<n;i++)
{
sumx += x[i];
sumx2 += sqr(x[i]);
sumxy += x[i] * y[i];
sumy += y[i];
sumy2 += sqr(y[i]);
}
denom = (n * sumx2 - sqr(sumx));
if (denom == 0) {
// singular matrix. can't solve the problem.
*m = 0;
*b = 0;
//if (r) *r = 0;
return 1;
}
*m = (n * sumxy - sumx * sumy) / denom;
*b = (sumy * sumx2 - sumx * sumxy) / denom;
if (r!=NULL) {
*r = (sumxy - sumx * sumy / n) /
sqrt((sumx2 - sqr(sumx)/n) *
(sumy2 - sqr(sumy)/n));
}
return 0;
}
void sgolayfilt(void){
//for(i=0;i<256;i++) printf("%d\n",ADC_ConvertedValue[i]);
if (!check)
{
for (i=0;i<4;i++)
{
ADC_ConvertedValueLocal = (float)
ADC_ConvertedValue[i]/4096*2.5;
placeholder[i] = ADC_ConvertedValueLocal;
}
check = 1;
}
for(i=0;i<256;i++)
{
if(i<4)
{
for(j=i;j<4;j++) y[j-i] = placeholder[j];
for(j=4-i;j<8;j++)
{
ADC_ConvertedValueLocal = (float)
ADC_ConvertedValue[j+i-4]/4096*2.5;
y[j] = ADC_ConvertedValueLocal;
}
}
else
{
for(j=i-4;j<i+4;j++)
{
ADC_ConvertedValueLocal = (float)
ADC_ConvertedValue[j]/4096*2.5;
y[j-i+4] = ADC_ConvertedValueLocal;
}
}
pass = linreg(8, x, y, &m, &b, &r);
if (pass==0) Send_float_Data[i] = (5 * m + b);
else
{
ADC_ConvertedValueLocal = (float)
ADC_ConvertedValue[i]/4096*2.5;
Send_float_Data[i] = ADC_ConvertedValueLocal;
}
}
for(i=0;i<4;i++) placeholder[i] = y[4+i];
}
This is for the original filter that works just fine save the actual filtering:
void IIR_filter(void)
{
for(i=0;i<256;i++)
{
ADC_ConvertedValueLocal =(float) ADC_ConvertedValue[i]/4096*2.5;
x0=ADC_ConvertedValueLocal;
w0[0]=IIR_50Notch_A[0]*x0-IIR_50Notch_A[1]*w0[1]-
IIR_50Notch_A[2]*w0[2];
y0=IIR_50Notch_B[0]*w0[0]+IIR_50Notch_B[1]*w0[1]+IIR_50Notch_B[2]*w0
[2];
x1=y0;
w1[0]=IIR_High_A[0]*x1-IIR_High_A[1]*w1[1]-IIR_High_A[2]*w1[2];
y1=IIR_High_B[0]*w1[0]+IIR_High_B[1]*w1[1]+IIR_High_B[2]*w1[2];
Send_float_Data[i]=y1;
w0[2]=w0[1];
w0[1]=w0[0];
w1[2]=w1[1];
w1[1]=w1[0];
}
}
And these are the variable declarations:
__IO unsigned char s[50];//
extern __IO uint16_t ADC_ConvertedValue[256];
__IO float ADC_ConvertedValueLocal;
__IO float Send_float_Data[256];
__IO int Send_int_Data[256];
volatile char Send_char_data[4];
__IO float placeholder[4];
float w0[3]={0};
float w1[3]={0};
float x0=0,x1=0;
float y0=0,y1=0;
float x[8] = {1,2,3,4,5,6,7,8};
float y[8];
float m,b,r;
unsigned int pass;
unsigned int i=0,j;
_Bool check = 0;
I don't have much experience with C and so I'm looking for help on how should I modify my code so that "sgolayfilt()" interacts with the data like "IIR_filter" does and not mess up the arrays.
EDIT After going back and looking through it a bit more the pre-filter array "ADC_ConvertedValue" encounters the error the moment I call the faulty function. I placed the two function calls in the same place and the "printf" statements at the very start of the function definitions themselves and the original can print the values within the array regardless while the faulty function can't.
I have a homework to implement an FIR filter in C and I wonder whether you think I understood the assignment correctly. The program I wrote that I think solves the problem is:
#include <stdio.h>
float FIRfloats[5];
void floatFIR(float newsample)
{
int i;
float sum=0;
FIRfloats[0]=newsample*0.0299;
FIRfloats[1]=FIRfloats[2]*0.4701;
FIRfloats[2]=FIRfloats[3]*0.4701;
FIRfloats[3]=FIRfloats[4]*0.0299;
/* sum */
for(i=0;i<5;i++)
{
sum=sum+FIRfloats[i];
}
printf("Sum: %f\n", sum);
}
int main ()
{
float n=0.0f;
while (scanf("%f", &n) > 0)
{
floatFIR(n);
}
return 0;
}
And the specification is
Before a new sample xk arrives the old samples are shifted to the
right and then each sample is scaled with a coefficient before the
result yk, the total sum of all scaled samples, is calculated
Coefficients should be c0=0.0299, c1=0.4701, c2=0.4701, c3=0.0299.
Do you think that I solved the assignment correctly? I think it seemed too easy and therefore I wonder.
I'm afraid the implementation provided in the question will not provide the correct results.
In FIR (Finite Impulse Response) filter with 4 coefficients the output series (y) for input series (x) is:
y[t] = c0*x[t] + c1*x[t-1] + c2*x[t-2] + c3*x[t-3]
Therefore the implementation should be similar to:
/* add includes (stdio.h and whatever else you'll need...) */
float floatFIR(float inVal, float* x, float* coef, int len)
{
float y = 0.0;
for (int i = (len-1) ; i > 0 ; i--)
{
x[i] = x[i-1];
y = y + (coef[i] * x[i]);
}
x[0] = inVal;
y = y + (coef[0] * x[0]);
return y;
}
main(int argc, char** argv)
{
float coef[4] = {0.0299, 0.4701, 0.4701, 0.0299};
float x[4] = {0, 0, 0, 0}; /* or any other initial condition*/
float y;
float inVal;
while (scanf("%f", &inVal) > 0)
{
y = floatFIR(inVal, x, coef, 4);
}
return 0;
}
This does the shift and multiplication at the same loop (which does not affect results - only is more efficient.)
If you want to follow the spec exactly, you can change floatFir like this:
float floatFIR(float inVal, float* x, float* coef, int len)
{
float y = 0.0;
for (int i = (len-1) ; i > 0 ; i--)
{
x[i] = x[i-1];
}
x[0] = inVal;
for (int i = 0 ; i < len ; i++)
{
y = y + (coef[i] * x[i]);
}
return y;
}