C program to calculate mathematical correlation function/autocorrelation function - c

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main ()
{
double g_1, e_1, e_2, e_3, e_4, e_5;
int k;
// double e[k];
e_1 = 3.0;
e_2 = 9.0;
e_3 = 27.0;
e_4 = 81.0;
e_5 = 243.0;
g_1 = ((e_1*e_2 + e_2*e_3 + e_3*e_4 + e_4*e_5)/5) - (((e_1)* + (e_2) + (e_3) +(e_4) + (e_5)/5)*((e_1)* + (e_2) + (e_3) +(e_4) + (e_5)/5));
printf("\n\n this is g(1): %f",g_1);
return (0);
}
I am trying to write a program that calculates the correlation between values. The mathematical function I have is the autocorrelation function or mathematical correlation function which is
g(T) = sum(from t = 1 to m-T) [ (e_t)*(e_(T+t)] - (sum(from t = 1 to m) [e_t/m] )^2
where m is the number of values I have.
Above I have tried to do the simplest version by taking 5 numbers and just plugging them into the formula. But eventually I need to be able to read a file containing any number of values from 100 to 5000 and find the correlation between them. I will worry about reading the file to the entries of an array later but first I would like to know is there a logical way of doing this using arrays?
For example I tried to do the following:
e[1] = 3.0;
e[2] = 9.0;
e[3] = 27.0;
e[4] = 81.0;
e[5] = 243.0;
for(k=1;k<=5;k++)
{
g[k]= ((e[k]*e[k+1] + e[k+1]*e[k+2] + e[k+2]*e[k+3] + e[k+3]*e[k+4])/5) - (((e[k] + e[k+1] + e[k+2] + e[k+3] + e[k+4])/5)*((e[k] + e[k+1] + e[k+2] + e[k+3] + e[k+4])/5))
}
But this would only make sense for k=1, because by the time it gets to k = 5, then k+1 will be 6, k+2 will be 7.. and I don't have these values.. But I'm not sure how exactly to program this.. Can anybody help?
Thank you
This is the formula using MathJax
g(\tau) = \sum_{\tau_{0}=1}^{m-\tau} ((\epsilon_{\tau{_0}} * \epsilon_{\tau+\tau_{0}})/m) - (\sum_{\tau_{0}=1}^m \epsilon_{\tau_{0}}/m)^2
an alternative form of the formula is:
g(\tau) = <\epsilon_{\tau_{0}}\epsilon_{\tau_{0}+\tau}>-<\epsilon_{\tau_{0}}>^2
where means expectation of a.

This is more of a how to read a math expression problem. It seems like in your example, m = 5, so the sums never reference beyond that.
I'm not entirely clear on your equation. Have tried Mathjax, but the formula is still not clear to me, but...
When translating a math expression to code, think of the summation sign (sigma) as equivalent to a for loop!
when writing the code, write (initially) in the most explicit way possible. For this problem code TWO for loops, one after the other, NOT nested. Each for loop does part of the calculation for g(k).
Get this to work for g(1). Then code a third for loop that wraps or surrounds the two loops you just got working. This loop will calculate g(1), g(2), etc. Note. if m is 5 and you only have 5 data points then you can only compute g(1), if m is 6 you can compute g(1) and g(2), etc.
Hope this helps, please post if you more information or questions.
To answer your comment, the following for loop implements a sum or sigma. Note. This is NOT exactly what your code should do, but it does demo using two for loops.
int g1; x = 0; y = 0;
int i;
// compute x = sum(g(i)) + sum(f(i))
// sum i = 0 to 2 [g(i)]
for (i=0; i < 3; i++) {x += g[i];}
// sum i = 0 to 1 [f(i)];
for (i=0; i < 2; i++) {y += f[i];}
g1 = x - y^2;

The C code you are looking for would be in this form:
int tau = 7
int m = 80;
double *e; /* An array filled with m values */
double lhs,rhs,answer;
int tau0;
/* Left Summation */
for(sum=0,tau0=1; tau0 < m-tau; ++tau0)
sum += e[tau0] * e[tau+tau0];
lhs = sum / m;
/* Right Summation */
for(sum=0,tau0=1; tau0 < m; ++tau0)
sum += e[tau0] / m;
rhs = sum * sum;
answer = lhs - rhs;
Hopefully this get you closer to your solution.

Related

Logic for formula calculation

I need to compute the following problem in code:
x0 = 2 and xi = (−1/2) * x(sub i - 1) * sqrt(x(sub i - 1))
find the result of (1/e^(x1 + x2 + x3 + ...)).
(Or as marked up text)
Write a function of an appropriate type that calculates and returns the result of:
e(x1-1 - x2-1 + x3-1 - x4-1 + ...), for n elements, defined as: x0 = 2 and xi = -½√|xi-1|
It has to be done in C but I am just trying to figure out the logistics of it.
What I have thought till now : x0 has to be a variable initialized with 2 along with x1. x2, x3... will be calculated in a recursive function n-1 times. I am not sure how the results should be stored, also a variable or maybe an array? Would an array be appropriate??
Thank you.
Would it not be simpler to do it iteratively like this? I'm not actually sure if this generates the correct answer but this seems to be what your formula would imply.
long double
compute(unsigned n)
{
long double x = 2.0L;
for (unsigned i = 0; i < n; ++i)
x = (-(1.0L/2.0L) * x) * sqrtl(fabsl(x));
return x;
}

Finite element analysis, 1D

I want the output to be values of C, at all range of i and t in the loops.
When I run it, I get error in sym/subref, L_tilde, idx.
I do not know what it means.
syms C;
alphaX=0.05;
DiffCoef = 5*10^-5
v = 0.1;
L = 10; xZones = 100;
dx = L/xZones;
T = 150;
u = 0.1;
dt= 0.005;
t = 150;
D = DiffCoef + (alphaX * u);
for i = 1:xZones
for t = 1:xZones
(C(i,t+dt) - C(i,t))/dt = -u(C(i+1,t +dt) - C(i,t+dt))/dx + D(C(i+1,t+dt) - 2*(C(i,t+dt) + C(i-1,t+dt)))/(dx)^2
end
end
Assuming this is Matlab code, there are some problems:
1) you cannot assign two outputs so the statement
(C(i,t+dt) - C(i,t))/dt = ...
is illegal. Matlab expressions can only return one output (without using for example "deal"), so in your case you would have to rearrange your expression as maybe
C(i,t+dt) = ...
C(i,t) = ...
Moreover, as this seems it is a time difference formula typically anything f(t+dt) is the unknown (left hand side), and f(t) are the known values as previous time step (right hand side) so that
f(t+dt) = dt*old_rhs - f(t)
In your case you have prescribed _C(i,t_dt)_ which seems very unusual, so please check your equations.

Generate MxN Matrix with MatLab Anonymous Function

Imagine for instance we have the following functions:
f = #(n) sin((0:1e-3:1) .* n * pi);
g = #(n, t) cos(n .^ 2 * pi ^2 / 2 .* t);
h = #(n) f(n) * g(n, 0);
Now, I would like to be able to enter an array of values for n into h and return a sum of the results for each value of n.
I am trying to be efficient, so I am avoiding the novice for-loop method of just filling out a pre-allocated matrix and summing down the columns. I also tried using arrayfun and converting the cell to a matrix then summing that, but it ended up being a slower process than the for-loop.
Does anyone know how I might do this?
The fact is the "novice" for-loop is going to be competitively as fast as any other vectorized solution thanks to improvements in JIT compilation in recent versions of MATLAB.
% array of values of n
len = 500;
n = rand(len,1);
% preallocate matrix
X = zeros(len,1001);
% fill rows
for i=1:len
X(i,:) = h(n(i)); % call function handle
end
out = sum(X,1);
The above is as fast as (maybe even faster):
XX = cell2mat(arrayfun(h, n, 'UniformOutput',false));
out = sum(XX,1);
EDIT:
Here it is computed directly without function handles in a single vectorized call:
n = rand(len,1);
t = 0; % or any other value
out = sum(bsxfun(#times, ...
sin(bsxfun(#times, n, (0:1e-3:1)*pi)), ...
cos(n.^2 * t * pi^2/2)), 1);

How many times the function will be invoked?

Here i have the loop:
for (i = n; i < 2*n; i += 4) {
for (j = 0; j < 3*i; j += 2) {
function();
}
}
How can i count amount of calls (in a term of n) of function() without running this code?
As the idea i think i can use arithmetic progression, which has the sum is S = (a1 + ak) * k / 2, where a1 - is amount of iterations of inner loop while i has initial value and ak - is amount of iterations of inner loop while i has final value.
But i cannot express it as a one formula with n as a variable.
Do you have any ideas about that?
The inner loop performs 3*i/2 calls. The outer loop has i=n, n+4, n+8 .. 2n-4. Therefore we have:
count = 3*n/2 + 3*(n+4)/2 + 3*(n+8)/2 + ... 3*2*n/2 =
= 3/2 * (n + (n+4) + (n+8) + .. + (2n-4)) =
= 3/2 * (3n^2-4n) / 8 =
= (9n^2 - 12n) / 16
(Edit: there may still be small inaccuracies that need to be fixed)
Edit #2 - I followed self's correction, and now I get the expected result.
Well, you've got the formula for arithmetic progression. When i = n, the inner loop goes 3n/2 times (more or less -- you may have to convert to a whole number). You may have to tweak the upper end a bit because there's no guarantee that n is divisible by 4, but you can do the same for the final loop. And it will run n/4 times (again convert to whole number).
Below are the formal steps that would allow you to deduce the exact number of times function() would execute:
The outer loop will execute n + ceil(n/4) - 1 times, the inner loop depends on the outer loop. I tried to detail as much as possible to make this solution clear enough.

Replace for loop with formula

I have this loop that runs in O(end - start) and I would like to replace it with something O(1).
If "width" wouldn't be decreasing, it would be pretty simple.
for (int i = start; i <= end; i++, width--)
if (i % 3 > 0) // 1 or 2, but not 0
z += width;
start, end and width have positive values
As someone else mentioned, this is probably easiest to think of as the sum of two series.
x x+3 x+6 ... x+3N
+ x+3N x+3(N-1) x+3(N-2) ... x
-----------------------------------
2x+3N 2x+3N 2x+3N ... 2x+3N
The above can be simplified to
(2x+3N)(N+1)
Which means the sum of one of them is really ...
(2x+3N)(N+1)/2
This equation would need to be applied for both series. It is possible that N would be different for both.
Thus, all you have to do is determine your starting point, and the number of items in the series. That shall be left as an exercise for the student.
Hope this helps.
Notice that
width == initial_width - (i - start)
so the summation can be rewritten as
end
—————
\ (initial_width + start - i)
/
—————
i=start
i mod 3 ≠ 0
end ⌊end/3⌋
————— —————
== \ (initial_width + start - i) —— \ (initial_width + start - 3j)
/ /
————— —————
i=start j=⌈start/3⌉
The rest should be simple.
It's probably easiest to think of this as the sum of two separate series, one for when i%3 = 1 and the other for when i%3=2. Alternatively, you could figure it as the sum for all values of i minus the sum for i%3=0. For the sake of argument, let's look at the first half of the latter approach: summing all the values of width.
In this case, width will start at some initial value, and each iteration its value will be reduced by 1. In the last iteration, its value will have been reduced by (end-start). Perhaps it's easiest to think of it as a triangle. Just to keep things simple, we'll use small numbers -- we'll start with width = 5, start = 1 and end = 5. Perhaps it's easiest to draw a diagram:
Values of width:
*
**
***
****
*****
What we're really looking for is the area of that triangle -- which is a pretty well-known formula from elementary geometry -- 1/2ab, where a and b are the lengths of the two sides (in this case, defined by the initial value of width and end-start). That assumes it really is a triangle though -- i.e. that it decrements down to 0. In reality, there's a good chance that we're dealing with a truncated triangle -- but the formula for that is also well known (1/2a1b + 1/2a2b, where the a's are the heights of the right and left sides, and b is the width.
I came up with this ugly method:
int start; // = some number
int end; // = ...
int initialwidth; // = ...
int each = (end+1)/3 - (start-1)/3 - 1;
int loop = 2*(3-(start+2)%3)+1;
int total = each*loop + 3*each*(each-1) + (start%3==1) + (end-start)*(end%3==1);
int result = -total + initialwidth*(1 + end - start - end/3 + (start-1)/3);
total will give the sum of (i-start)s when (i%3 > 0) for i=start to end.
result will give the sum of widths added to z.
The closed form of sum(i=1 ... n) i is (n)(n+1)/2. You should be able to use this with a little algebra to find a closed form that provides you with the result you're looking for.
Do you want something like z = 2 * width * (start - end) / 3 + (start - end) % 3? (not quite right, but close enough to get you on the right track.
This isn't a full answer, but you should notice that:
x = end - start;
k = ~(-1 << x); // I think (width * k)>>x would be your z except if you didn't have the contidional
and that a value that from LSB up has two bits set, one bit cleared, two bits set, one bit cleared (0x...011011011) could be used to compute where the %3 is 0.
R = k - (k & 0x...011011011); // This is the series 3 + (3 << 3) + (3 << 6) ...
z = (R * width)>>x; // I think.
Just something to try. I've probably made some kind of mistake.

Resources