How to take a moving mean of an array - c

Can some one please help me on this issue as I have spent time going around it without making any headway.
I have data in an array of size say 3O.
I want to take the first five elements of the array, find their mean value. Store the value in another array
Then move to the second element of the array,from their find the mean value of the 5 succeeding elements.store the value in the array as above.
Then wove to the 3rd element,do the same thing above till the last element which is 30 in this case.
float tabdata[] = {1,2,3,4,...,30};
char *store;
float sum;
for(int j=0;j<tabdata[30-1];j++)
sum += tabdata[j];
if (j=5)
{
float mean= sum/5;
store[j]=mean;
sum=0;
for(i=j;i>tabdata[30-1];i++)
sum +=tabdata[i];
if (j=5)
---
----
....need help to complete this loop please.

Just add 1/5 of the next element and subtract 1/5 of the first element in the current window at every step. The only thing you need to worry about is floating point precision.

You can fix up the sum as you go:
#include <stdlib.h>
#include <stdio.h>
int main()
{
float tabdata[] = {1,1.5,1.8, 2, 3, 4, 5,6,7,8,9,10,11,12,13,14,15,161,7,18,19,20,21,30};
float* result;
float sum;
int count = sizeof(tabdata)/sizeof(tabdata[0]);
int i;
result = (float *)malloc((count - 4) * sizeof(float));
/* Initialise with the first five elements */
for (i=0;i<5;i++)
{
sum += tabdata[i];
}
result[0] = sum / 5.0;
for (i=5;i<count;i++)
{
sum -= tabdata[i-5];
sum += tabdata[i];
result[i-4] = sum / 5.0;
}
for (i=0;i<count-4;i++)
{
printf("%f\t%f\n",tabdata[i],result[i]);
}
for (;i<count;i++)
{
printf("%f\n",tabdata[i]);
}
free(result);
}

I think that what you might want to use is the modulus operator (%) which will give you the rest of the division. You will get something like this:
if ((j+1) % 5 == 0)
{
float mean= sum/5;
store[j/5]=mean;
sum=0;
}
This way, at every 5 iterations, the code will be executed.

Haven't tested this but should work:
float tabdata[] = {1, 2, 3, ..., 30};
float *result;
float sum;
int count = sizeof(tabdata)/sizeof(tabdata[0]);
result = (float *)malloc((count - 4) * sizeof(float));
for (int j = 0; j < count - 5; j++) {
sum = 0;
for (int k = j; k < j + 5; k++) {
sum += tabdata[k];
}
result[j] = sum / 5;
}
// ...
free(result);

Related

Confusion in arrays

Recently I was learning about arrays passing to functions (by passing their base address to a pointer defined as parameter in function and then using pointer arithmetic for extracting the whole array subsequently)
For practice I was asked to calculate the average marks of a class of 70 students with their marks listed in an array named "marks" and was asked to define a variable with parameter as a pointer
and calculate average from there.
The data given to me was that student 1 scored 40 , student 2 scored 41, student 3 scored 42....and so on.
Here is my attempt at it:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
float average(int *b)
{
int sum = 0;
for (int i = 1; i <= 70; i++)
{
sum = sum + *b;
b = b + 1;
}
printf("the value of sum is %d\n", sum); // this value is changing every time I run the program
return (((float)sum) / 70);
}
int main()
{
int marks[70];
marks[0] = 40;
for (int i = 0; i < 68; i++)
{
marks[i + 1] = marks[i] + 1;
}
printf("the value of marks of 10th child is %d\n", marks[9]); // Just for checking if I am correct!(yes! the ans does come out to be 49!)
printf("the value of average marks of the class is %f\n", average(&marks[0]));
return 0;
}
to my surprise the value kept changing every time I ran it. Can anyone give a hint where am I wrong?
I was asked to calculate the average marks of a class of 70 students with their marks listed in an array named "marks"
In the posted code, we can find the following declaration
int marks[70];
The size is correct, but note that it's uninitialized, so that the values of its elements are undeterminated. The code, though, tries to assign the correct values immediately after.
marks[0] = 40; // "student 1 scored 40, student 2 scored 41, student 3 scored 42...
// and so on."
for (int i = 0; i < 68; i++)
{ // ^^^^^^
marks[i + 1] = marks[i] + 1;
} // ^^^^^
The last mark assigned is marks[67 + 1], which leaves marks[69] (the actual last element of the array) undeterminated.
There are many ways to achive the correct result, some may find the following appropriate.
int marks[70] = { 40 };
for (int i = 0; i + 1 < 70; ++i)
{ // ^ ^^^^^^^^^^
marks[i + 1] = marks[i] + 1;
}
I was learning about arrays passing to functions (by passing their base address to a pointer defined as parameter in function and then using pointer arithmetic for extracting the whole array subsequently)
Using indices often yields more readable code, so I won't use "pointer arithmetic" in the following snippet.
I'd suggest to always pass the size of the array, not only the pointer.
Note how many "magic" numbers, like 70 and the wrong 68, are spread (and repeated) throughout the posted code, limiting its generality and rising the chances of errors.
I'd also extract the logic of the previous snippet into a separate function, easily modifiable and testable.
#include <stdio.h>
double average(size_t n, int *marks)
{
long sum = 0;
for (size_t i = 0; i < n; ++i)
{
sum += marks[i];
}
return (double)sum / n;
}
void fill_linear(size_t n, int *arr, int first_value)
{
for (size_t i = 0; i < n; ++i)
{
arr[i] = first_value++;
}
}
int main(void)
{
enum { n_students = 70 };
int marks[n_students];
fill_linear(n_students, marks, 40);
printf("Average: %.1f\n", average(n_students, marks)); // Average: 74.5
return 0;
}
You're problem is related to the fact (as mentioned in my comment) that your array is uninitialized.
The memory for it has been allocated but its still random jumble data.
Luckily you overwrite that data for all entries in the array, except for the last one. The last entrance is basically a random value at this point.
So thats the reason the output keeps changing, your actuall bug is a bit simpler.
In the for loop where you calculate the sum, you iterate from i = 0 to i = 67. So with the +1 offset you change all the entries from 1 to 68, so the last entrance (marks[69]) doesn't get touched.
Fixed code:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
float average(int *b) {
int sum = 0;
for (int i = 1; i <= 70; i++) {
sum = sum + *b;
b = b + 1;
}
printf("the value of sum is %d\n",
sum); // this value is changing every time I run the program
return (((float)sum) / 70);
}
int main() {
int marks[70];
marks[0] = 40;
for (int i = 0; i < 68; i++) {
marks[i + 1] = marks[i] + 1;
}
printf("the value of marks of 10th child is %d\n",
marks[9]); // Just for checking if I am correct!(yes! the ans does come
// out to be 49!)
printf("the value of average marks of the class is %f\n", average(&marks[0]));
return 0;
}
PS:
In the average function ,you use pointer arithmetic to loop over the input array, which is considered bad practice by a lot of people. Also, youre basiaclly not using the for-loop incrementor variable you create (int i). A easier and safer way to do this is :
float average(int *b) {
int sum = 0;
for (int i = 0; i < 69; i++) {
sum += b[i];
}
printf("the value of sum is %d\n",
sum); // this value is changing every time I run the program
return (((float)sum) / 70);
}

Imprecise average at run time

I am trying to solve a problem and I've run into a bit of an issue.
I have to find the running average of a series of numbers.
Example:
input 4 2 7
output 4 3 4.3333
Now here's the problem although I get the answer, it is not the precise answer.
Accepted Output: accuracy difference shown in the image
290.6666666667
385.4000000000
487.8333333333
477.4285714286
496.4444444444
...
523.8571166992
506.0454406738
495.3043518066
I can't find whats wrong. Some help would be highly appreciated.
#include<stdio.h>
main(){
int n;
printf("set:");
scanf("%d",&n);
float arr[n+1],resarr[n+1];
float sum=0;
for(int i=1; i<=n; i++){
scanf("%f",&arr[i]);
sum=arr[i]+sum;
float res= sum/(float)i;
resarr[i]=res;
}
int i=1;
while(i<=n) {
printf("%0.10f\n",resarr[i]);
i++;
}
return 0;
}
Here
for(int i=1; i<=n; i++){ }
you are trying to access out of bound array elements, this certainly causes undefined behavior as let's assume if n is 5 then you are accessing arr[5] also which doesn't exist.
C doesn't perform array boundary condition check, its programmer responsibility to not to access out of bound elements else it causes UB.
In C array index starts from 0 not from 1. So better start rotating loop from 0 to n. For e.g
for(int i=0; i<n; i++) {
scanf("%f",&arr[i]);
/* some code */
}
Code fails to achieve the desired accuracy as it is using float rather than double. #Some programmer dude
Typical float is precise to 1 part in 223. For printing to 0.0000000001, better to use double which is typically precise to 1 part in 253.
#include<stdio.h>
int main(void) {
//float arr[n + 1], resarr[n + 1];
//float sum = 0;
double arr[n + 1], resarr[n + 1];
double sum = 0;
...
// scanf("%f", &arr[i]);
scanf("%lf", &arr[i]);
...
// float res = sum / (float) i;
double res = sum / i; // cast not needed as `sum` is `double`
...
}
Iterating from 1 is not idiomatic in C. More common to iterate starting at 0.
size_t is best for array sizing and indexing. int may be too narrow. Of course with small arrays, it makes scant difference.
#include<stdio.h>
int main(void) {
printf("set:");
size_t n;
scanf("%zu", &n);
double arr[n], resarr[n];
double sum = 0;
for (size_t i = 0; i < n; i++) {
scanf("%lf", &arr[i]);
sum = arr[i] + sum;
double res = sum / (i+1);
resarr[i] = res;
}
for (size_t i = 0; i < n; i++) {
printf("%0.10f\n", resarr[i]);
}
return 0;
}
More robust code would check the input from the user it insure it is valid, allocate rather than use a VLA if n is allowed to be large, flush output before reading, etc.
Note that array arr[] is not needed, just a single double for the input and sum.

Fractions: Sum and difference in C programming

I'm facing problems in writing a program in C that calculates S, being S = {1/50 - 3/48 + 5/46...} with 9 elements. I don't know how to use the DIFFERENCE operator followed by a SUM operator, and I MUST use the for structure.
Here's the program I wrote:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int n, d, S, i;
i = 0;
n = 1;
d = 50;
S = n / ((double)d);
for (i = 0; i < 4; i++) {
n += 2;
n -= 2;
S = S + (n / ((double)d));
S = S - (n / ((double)d));
}
printf("%d", S);
return 0;
}
I know that the variable declarations may be wrong and that's exactly where I get confused. I decalred S as an integer but put d (denominator) to double 'cause the result must be a decimal number, of course.
Can anybody help me??
The output I'm getting is: 0
Perhaps like this. The most important point, is to use the double type, because the int type can only hold whole numbers.
#include <stdio.h>
int main (void) {
int i;
double sign = 1.0; // sign
double num = 1.0; // numerator
double div = 50.0; // divisor
double sum = 0.0; // series sum
for (i = 0; i < 9; i++) {
sum += sign * num / div; // accumulate the term
num += 2.0; // numerator +2
div -= 2.0; // divisor -2
sign *= -1.0; // alternate the sign
printf("%f\n", sum); // show double result
}
return 0;
}
Program output:
0.020000
-0.042500
0.066196
-0.092895
0.121390
-0.153610
0.188496
-0.228171
0.271829
Different things to say about your code.
First you cannot use an integer for your sum since you want a floating point result.
Then as mentioned in comments you are using successive operations that result in not changing the variable
n+=2; n-=2;
You could simply do something like :
double S = 0.0; int N=9;
for(i=0; i < N; ++i) {
S += ( (i % 2 == 0)?(1.0):(-1.0) ) * (2.0*i+1)/(50-(2.0*i+1));
}
The instruction (i % 2 == 0)?(1.0):(-1.0) pick 1 if 'i' is even and -1 if 'i' is odd.
Finally if S is no longer an int you must change your printf with a floating point format like for example '%f'.
Check if what you're looking for is the following code:
#include <stdio.h>
#include <stdlib.h>
void main () {
int n = 1, d = 50, i = 0, signal = 1;
double S = n / (double) d;
for (i = 0; i < 8; i++) {
n += 2;
d -= 2;
signal = -signal;
S += signal * n/(double)d;
}
printf("%f", S);
}
I think you're missing S is a double number. int/double = double, but youre assign this math in a int variable.

Finding the nth fib number, in O(logn)

I am trying to solve this: SPOJ problem.
And after some research I found out that it comes down to a simple calculation of the nth fib number, however n can get really large so an O(n) solution won't do any good. Googling around, I found that you can calculate the nth fib number in O(logn) and also a code sample that does exactly that:
long long fibonacci(int n) {
long long fib[2][2] = {{1,1},{1,0}}, ret[2][2] = {{1,0},{0,1}}, tmp[2][2] = {{0,0},{0,0}};
int i, j, k;
while (n) {
if (n & 1) {
memset(tmp, 0, sizeof tmp);
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
for (k = 0; k < 2; k++)
tmp[i][j] = (tmp[i][j] + ret[i][k] * fib[k][j]);
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
ret[i][j] = tmp[i][j];
}
memset(tmp, 0, sizeof tmp);
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
for (k = 0; k < 2; k++)
tmp[i][j] = (tmp[i][j] + fib[i][k] * fib[k][j]);
for (i = 0; i < 2; i++)
for (j = 0; j < 2; j++)
fib[i][j] = tmp[i][j];
n /= 2;
}
return (ret[0][1]);
}
I tried to modify it for the problem and am still getting WA: http://ideone.com/3TtE5m
Am I calculating the modular arithmetic wrong? Or is something else the issue?
You mean the nth Fibonacci number I hope.
In order to do it you need a matrix decomposition of Fibonacci numbers described here.
The basic idea is you take the Donald E. Knuth matrix identity form for a Fibonacci number which is:
And instead of calculating the Fibonacci numbers in the traditional way you will try and find the matrix to the power of (k) where k is the given number.
So this is solving the problem in k matrix multiplications, not really helpful since we can do it in much easier way.
But wait! We can optimise the matrix multiplication. Instead of doing the k multiplications we can square it first and then do the half of the multiplications. And we can keep on doing it. So if the given number is 2a then we can do it in a steps. By keeping squaring the matrix.
If the number is not a power of 2 we can do the binary decomposition of a number and see whether to take the given squared matrix into final product or not.
In your case after each multiplication you also need to apply modulo operator 123456 to each matrix element.
Hope my explanation helps if not see the link for a clearer and longer one.
There is actually one more caveat of the task: as you are asked to provide some Fibonacci number modulo a given number, you should also prove that taking the remainder of each matrix element doesn't change the result. In other words if we multiply matrices and take remainder that we are actually still getting the Fibonacci number remainders. But since the remainder operation is distributive in addition and multiplication it actually does produce the correct results.
The Fibonacci numbers occur as the ratio of successive convergents of the continued fraction for , and the matrix formed from successive convergents of any continued fraction has a determinant of +1 or −1.
The matrix representation gives the following closed-form expression for the Fibonacci numbers i.e.
The matrix is multiplied n time because then only we can get the (n+1)th Fibonacci number as the element at the row and the column (0, 0) in the resultant matrix.
If we apply the above method without using recursive matrix multiplication, then the Time Complexity: O(n) and Space Complexity: O(1).
But we want Time Complexity: O(log n), so we have to optimize the above method, and this can be done by recursive multiplication of matrix to get the nth power.
Implementation of the above rule can be found below.
#include <stdio.h>
void multiply(int F[2][2], int M[2][2]);
void power(int F[2][2], int n);
/*
The function that returns nth Fibonacci number.
*/
int fib(int n) {
int F[2][2] = {{1, 1}, {1, 0}};
if (n == 0)
return 0;
power(F, n - 1);
return F[0][0];
}
/*
Optimized using recursive multiplication.
*/
void power(int F[2][2], int n) {
if ( n == 0 || n == 1)
return;
int M[2][2] = {{1, 1}, {1, 0}};
power(F, n / 2);
multiply(F, F);
if (n % 2 != 0)
multiply(F, M);
}
void multiply(int F[2][2], int M[2][2]) {
int x = F[0][0] * M[0][0] + F[0][1] * M[1][0];
int y = F[0][0] * M[0][1] + F[0][1] * M[1][1];
int z = F[1][0] * M[0][0] + F[1][1] * M[1][0];
int w = F[1][0] * M[0][1] + F[1][1] * M[1][1];
F[0][0] = x;
F[0][1] = y;
F[1][0] = z;
F[1][1] = w;
}
int main() {
printf("%d\n", fib(15));
/*
15th Fibonacci number is 610.
*/
return 0;
}
There is a very simple algorithm, using only integers:
long long fib(int n) {
long long a, b, p, q;
a = q = 1;
b = p = 0;
while (n > 0) {
if (n % 2 == 0) {
long long qq = q*q;
q = 2*p*q + qq;
p = p*p + qq;
n /= 2;
} else {
long long aq = a*q;
a = b*q + aq + a*p;
b = b*p + aq;
n -= 1;
}
}
return b;
}
This is based on the identities of the Lucas sequence.

|c| Series 1+2x+3x^2+4x^3+....nx^(n-1)

First of all, I searched and all questions I found are similar but not exactly this one.
This is my first post here, I'm a beginner in programming and currently learning to code in C.
Been struggling with this code for about 5 hours now.
The question is create a program in C, using only loops (and not using pow(), using stdio.h library only).
The question is to get the user to give you two numbers - X and N
the program will print The result of the following equation:
1+2x+3x^2+4x^3+....+nx^(n-1)
For example for the input of - X=2 N=3
1*2^0 + 2*2^1 + 3*2^2
What the program will print is "17"
This is my attempt so far, I got to the Power function but I cant find a way to incorporate into the programm itself.
#include <stdio.h>
int main(void)
{
int i, j=0, b = 0;
float x, n;
double sum = 0, sumt=0;
do{
printf("Please enter two numbers \n");
flushall;
scanf("%f %f", &n, &x);
} while (x <= 0);
for (i = 1; i <= n; i++){
sum = x*x;
}
sumt += sum;
printf("%f", sum);
}
Instead of trying to create an implementation of pow, you will need to take advantage of the relationship between the terms of the expression.
The n-th term is nx^(n-1). The n-1-the term is (n-1)x^(n-2).
If we denote the n-th term as T(n) and denote the n-1-th term as T(n-1),
T(n) = T(n-1)*x*n/(n-1)
Given the starting value of the first term,
T(1) = 1
you can compute the subsequent terms using the above formula.
The following code should work.
// Initialize the values for N=1
term = 1;
sum = 1;
// Iterate starting from 2
for (i = 2; i <= n; i++){
term *= x*i/(i-1);
sum += term;
}
The working Program based on the tips given by the almighty #R_Sahu (And others ;D)
**
#include <stdio.h>
int main(void)
{
int i, j = 0, c = 0;
float x, n, b = 0;
double term, sum;
do {
printf("Enter Two Numbers\n");
flushall;
scanf("%f%f", &n, &x);
} while (x < 0);
for (i = 2; i < n + 2; i++)
{
term = 1;
sum = 1;
for (i = 2; i <= n; i++){
term *= x*i / (i - 1);
sum += term;
}
}
printf("The answer is %.lf ", sum);
}
I will not give you the code, but the reasoning you should follow
First you have to somehow get the data from the user (as a parameter, from stdio... whatever)
x = getFromUser
n = getFromUser
You will then need to init a temporary result
result = 0
How many times do you have to add? -> Exactly n times
for(ii=0;ii<n;ii++) {
result = result + pow((ii*x),(ii-1)) //There is something missing here, I'll let you guess what
}
But wait; you cannot use pow. So you have to program it by yourself (I guess that's the idea of the exercise)
then you need a function, and it has to return an int (actually, it may return even irrational numbers, but I don't think they will require you to do that)
int customPow(int base, int exponent) {
//Put your for in here, and may the pow be with you
}
You need to figure out the code yourself, but the general idea is as follows:
Create your own pow function which returns x*n.
int pow(int x, int n){
//use a for or while loop to calculate x (*x)n times.
//pay attention to the base cases (i.e., when n = 0, or 1 etc)
}
ans = 0;
for(i = 0 to N-1){
ans = ans + pow(x,i-1)*i;
}

Resources