Matlabs xcorr function in c - matlab

I am using the function
in = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
lag = 8;
out = xcorr(in, lag)
it produces the output:
out = [175,000000000000, 238,000000000000, 308, 384, 465, 550, 638, 728, 819, 728, 638, 550, 465, 384, 308, 238, 175,000000000000];
I do not understand from Matlabs documentation how to get those values. Is there any kind of formula that I can use for that?

In general matlab documentation put the formulas in a chapter named More about, look at this chapter to understand which formula matlab implements.
This is the link to the More about chapter of the xcorr function.
https://it.mathworks.com/help/signal/ref/xcorr.html#bubr0h6
For greater clarity look at this code:
in = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
lag = 8;
N = length(in);
correlation = zeros(2*lag,1);
for m = -8:8
correlation(m+8+1) = sum(in.*[zeros(1,abs(m)) in(1:N-abs(m))]);
end
where sum(in.*[zeros(1,abs(m)) in(1:N-abs(m))]); computes the sum of the product beetween in and its shifted version. To compute the shifted version of in simply padding the first m elements with zero and the N-m element are in(1:N-m). I've used the abs because the lag m is either negative or positive.
Try the code and also print [zeros(1,abs(m)) in(1:N-abs(m))] for various value of m to understand better how look the shifted version of the vector.
For homework: why we use [zeros(1,abs(m)) in(1:N-abs(m))] and not [zeros(1,abs(m)) in(1:N)]?
P.s in this case you are calculating the autocorrelation, so the y vector is x.
For more details about the theory check the Reference chapter to see which books matlab refers.

Related

Matlab resample time series for specific times, rather than frequencies

I have the following problem in Matlab:
I have a time series which looks like this:
size(ts) = (n,2); % with n being the number of samples, the first column is the time, the second the value.
Let's say I have:
ts(:,1) = [0, 10, 20, 30, 40];
ts(:,2) = [1, 3, 10, 6, 11];
I would like to resample the signal above to get the interpolated values at different times. Say:
ts(:,1) = [0, 1, 3, 15, 40];
ts(:,2) = ???
I had a look at the Matlab functions for signal processing but they are all only relevant for regular sampling at various frequencies.
Is there a built in function which would give me the above, or do I have to compute the linear interpolation for each new desired time manually? If so, do you have a recommendation to do this efficiently using vecotrized code (just started Matlab a month ago so still 100% at ease with this and relying on for loops a lot still).
For a bit of context, I'm using a finite difference scheme in series to investigate a problem. The output of one FD scheme is fed into the following. Due to the nature of my problem, I have to change the time stepping from one FD to the next, and my time steps can be irregular.
Thanks.
Since your data are 1-D you can use interp1 to perform the interpolation. The code would work as follow:
ts = [0, 10, 20, 30, 40; % Time/step number
1, 3, 10, 6, 11]; % Values
resampled_steps = [0, 1, 3, 15, 40]; % Time for which we want resample
resampled_values = interp1(ts(1, :), ts(2, :), resampled_step);
% Put everything in an array to match initial format
ts_resampled = [resampled_steps; resampled_values];
Or you can alternatively, following the same idea:
ts = [0, 10, 20, 30, 40; % Time/step number
1, 3, 10, 6, 11]; % Values
% Create resample array
ts_resampled = zeros(size(ts));
ts_resampled(1, :) = [0, 1, 3, 15, 40];
% Interpolate
ts_resampled(2, :) = interp1(ts(1, :), ts(2, :), ts_resampled(1, :));
You can even choose the interpolation method you want, by passing a string to the interp1 function. The methods are listed here
Note that this only work if you re-sample with time stamps within your original scope. If you want them outside you have to tell the function how to extrapolate using the key word 'extrap'. Detail here

Matlab cconv and circular convolution

My goal is to use Matlab to verify circular convolution calculations. I try to do this using cconv.
However, Matlab does not give the same answer to problems I know the answer for. Why?
An example is the circular convolution modulo 4 between [1, 2, 4, 5, 6] and [7, 8, 9, 3] as can be found in this paper by Abassi
According to the paper the answer is: [112, 91, 71, 88, 124].
But according to Matlab it is: [131, 127, 122, 106].
a = [1,2,4,5,6]
b = [7,8,9,3]
y = cconv(a,b,4)
ans =
131 127 122 106
What do I do wrong here?
y = cconv(a,b,5)
the 3rd argument is 5 not 4 for what the paper describes
The matlab code used in the Abbasi paper is written in the end :
A=fft(a);
B=fft(b);
y=ifft(A.*B);
I don't know why you use cconv if this doese the work.

Sequence in MATLAB

Write a single MATLAB expression to generate a vector that contains first 100 terms of the following sequence: 2, -4, 8, -16, 32, …
My attempt :
n = -1
for i = 1:100
n = n * 2
disp(n)
end
The problem is that all values of n is not displayed in a single (1 x 100) vector. Neither the alternating positive and negative terms are shown. How to do that ?
You are having a geometric series where r = -2.
To produce 2, -4, 8, -16, 32, type this:
>>-(-2).^[1:5]
2, -4, 8, -16, 32
You can change the value of 5 accordingly.
Though there are better methods, as mentioned in the answer by #lakesh. I will point out the mistakes in your code.
By typing n = n * 2, how can it become a vector?
By doing n=n * 2, you are going to generate -2, -4, -8, -16, ...
Therefore, the correct code should be:
n = -1
for i = 2:101 % 1 extra term since first term has to be discarded later
n(i) = -n(i-1) * 2;
disp(n)
end
You can discard first element of n, to get the exact series you want.
n(end)=[];

Expand an array by filling in with current values in MATLAB

I have a fairly simple issue and I just want to know if there's an easy way to do it in MATLAB (i.e. a function to do this rather than writing out loops or something myself).
Let's say I have a timeseries where Time is 1:1:1000 and Data is 2 * (1:1:1000) and I want to expand the array by making the Time and Data vector finer. Let's say that I want Time to be 1:0.1:1000 and Data to be 2 * (1:0.1:1000). Is there an easy way to tell MATLAB that to repeat the values of each vector 10 times (from 1 / 0.1 = 10) so that I can have something like this?:
Time: [1, 2, 3, 4, ...]
Data: [2, 4, 6, 8, ...]
to:
Time: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, ...]
Data: [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, ...]
You can use combination of reshape() and repmat() as follow:
Data = [2, 4, 6, 8, ...] % As stated in the question.
Data = reshape(repmat(Data, 10, 1), 1, []);
This is more time-efficient than the others like kron() or combination of sort() and repmat().
Two simulations were done and the results are shown in the following figures.
First: Simulation time vs. length of Data. Here I used N=100 instead of 10.
Second: Simulation time vs. repetition factor. Length of Data is 10000.
So you can select the best one according to the simulation results.
As seb proposed, you can use the function repmat. Here what I would do:
Data = [2, 4, 6, 8, ...];
Data = sort(repmat(Data,1,10));
You can use repmat
interval_size = 10;
Data = 2*(1:1:1000);
out_data = repmat(Data,interval_size,1);
out_data = out_data(:)';
Example Data:
time=1:50
data=2:2:100
t2=1:.1:50.9
For time=1:n this is very simple:
data(:,floor(t2))
If your original data has another time scale, use this:
[a,b]=ismember(floor(t2),time)
data(:,b)

How to get a regular sampled matrix in Scilab

I'm trying to program a function (or even better it it already exists) in scilab that calculates a regular timed samples of values.
IE: I have a vector 'values' which contains the value of a signal at different times. This times are in the vector 'times'. So at time times(N), the signal has value values(N).
At the moment the times are not regular, so the variable 'times' and 'values' can look like:
times = [0, 2, 6, 8, 14]
values= [5, 9, 10, 1, 6]
This represents that the signal had value 5 from second 0 to second 2. Value 9 from second 2 to second 6, etc.
Therefore, if I want to calculate the signal average value I can not just calculate the average of vector 'values'. This is because for example the signal can be for a long time with the same value, but there will be only one value in the vector.
One option is to take the deltaT to calculate the media, but I will also need to perform other calculations:average, etc.
Other option is to create a function that given a deltaT, samples the time and values vectors to produce an equally spaced time vector and corresponding values. For example, with deltaT=2 and the previous vectors,
[sampledTime, sampledValues] = regularSample(times, values, 2)
sampledTime = [0, 2, 4, 6, 8, 10, 12, 14]
sampledValues = [5, 9, 9, 10, 1, 1, 1, 6]
This is easy if deltaT is small enough to fit exactly with all the times. If the deltaT is bigger, then the average of values or some approximation must be done...
Is there anything already done in Scilab?
How can this function be programmed?
Thanks a lot!
PS: I don't know if this is the correct forum to post scilab questions, so any pointer would also be useful.
If you like to implement it yourself, you can use a weighted sum.
times = [0, 2, 6, 8, 14]
values = [5, 9, 10, 1, 6]
weightedSum = 0
highestIndex = length(times)
for i=1:(highestIndex-1)
// Get the amount of time a certain value contributed
deltaTime = times(i+1) - times(i);
// Add the weighted amount to the total weighted sum
weightedSum = weightedSum + deltaTime * values(i);
end
totalTimeDelta = times($) - times(1);
average = weightedSum / totalTimeDelta
printf( "Result is %f", average )
Or If you want to use functionally the same, but less readable code
timeDeltas = diff(times)
sum(timeDeltas.*values(1:$-1))/sum(timeDeltas)