Implement those functions using matlab - matlab

I have an array of samples of ECG signals 1250x1 double let us called it "a".
I need to implement 4 functions which represent features are used to characterize the signals. Energy, 4th Power,Nonlinear Energy and Curve Length
I manged to implement Energy and 4th Power
for i=1:1250
energy = sum(a.^2,i);
power4th = sum(a.^4,i);
end
Which produce 2 array (energy and power4th)
How I can produce the other 2 array? let us called them NonLE and CL.

Use vectorization instead of for loops to solve all 4 of the formulas you need
% generate some random numbers
a = rand(1000,1);
Energy = sum(a.^2);
Power4 = sum(a.^4);
NLEnergy = sum(-a(3:end).*a(1:end-2) + a(2:end).^2);
CurveLength = sum(a(2:end) - a(1:end-1));
The . operator allows element by element operations in a vector.

Actually I think you can implement your formulas without using for loop. You can use matrix multiplication characteristic. Try the code below:
len = 1250;
a = randi(10, len, 1); % // You didn' t give your vector so I generated random a..
Energy = ones(1, len) * (a.^2);
power4th = ones(1, len) * (a.^4);
NonLE = ones(1, len - 2) * ( -a(3:end) .* a(1:end-2) ) + ones(1, len - 1) * ( a(2:end).^2 );
CL = ones(1, len - 1) * ( a(2:end) - a(1:end-1) );

You don't really need a for loop for 3 of them:
energy = sum(a.^2);
power_4th = sum(a.^4);
curve_length = sum(diff(a));
For the last one, you can do something like:
nonLE = 0;
for k = 3 : length(a)
nonLE = nonLE + a(k - 1)^2 - a(k) * a(k - 2);
end

Related

MATLAB loop refactoring

I'm curious to know if there is a better way to express the following loop:
To = 1;
fileName = "fourier/signal.txt";
spectrum_left(abs(spectrum_left) < 1e-3) = 0+0i;
Ts = 1 / Fs;
t = 0:Ts:To-Ts;
signal = load(fileName, "-ascii");
Ns = numel(signal);
Fs = Ns / To;
fr = f(abs(spectrum_left) > 0)
a = abs(spectrum_left(abs(spectrum_left) > 0))
p = angle(spectrum_left(abs(spectrum_left) > 0))
signal_synth = 0;
len = length(a);
for i=1:len
a_i = a(i);
p_i = p(i);
f_i = fr(i);
s_i = a_i * cos(2*pi*f_i*t + p_i)
signal_synth = signal_synth + s_i;
end
Any suggestions are greatly appreciated. And Happy New Year!
In MATLAB, element-wise operators, that preceded by the period character (.), can be applied on arrays. I used (:) operator to convert the vectors to column vectors. Note that t is a row vector, when it is combined with column vectors the result will be a matrix that is formed by implicit expansion. In order to sum up the values the function sum is used that by default sums along the first dimension of the matrix and the result will be a row vector with the same size as t.
signal_synth = sum(a(:) .* cos(2 * pi * f(:) .* t + p(:)));
A more compact form using matrix multiplication:
signal_synth = a(:).' * cos(2 * pi * f(:) .* t + p(:));

Vectorize shuffle for blocks of matrix rows

I have a simple 5x15 matrix called mat_orig. I would like to divide this matrix into non-overlapping blocks, whereby each block is of length 3. That is equivalent to put three non-overlapping rows into one block (i.e. there are 5 blocks of size 3x5).
I would then like to shuffle mat_orig and generate a new matrix. I am using randi to randomly draw five blocks.
I succeeded in finishing my task using the code below. However, I am wondering if I can get rid of the for-loop? Can I apply vectorization?
mat_orig = reshape(1:75, 5, 15)';
block_length = 3;
num_blocks = size(mat_orig, 1) / block_length;
rand_blocks = randi(num_blocks, num_blocks, 1);
mat_shuffled = nan(size(mat_orig));
for r = 0 : num_blocks - 1
start_row_orig = r * block_length + 1;
end_row_orig = r * block_length + block_length;
start_row_random_blocks = ...
rand_blocks(r + 1) * block_length - block_length + 1;
end_row_random_blocks = ...
rand_blocks(r + 1) * block_length;
mat_shuffled(start_row_orig:end_row_orig, :) = ...
mat_orig(start_row_random_blocks:end_row_random_blocks, :);
end
You can do this with implicit expansion to create the blocks' indices, see the code comments for details.
mat_orig = reshape(1:75, 5, 15)';
block_length = 3;
num_blocks = size(mat_orig,1) / block_length;
% Get the shuffle order (can repeat blocks)
shuffIdx = randi( num_blocks, num_blocks, 1 ).';
% Expand these indices to fill the blocks
% This uses implicit expansion to create a matrix, and
% will only work in R2016b or newer.
% For older versions, use 'bsxfun'
shuffIdx = block_length * shuffIdx - (block_length-1:-1:0).';
% Create the shuffled output
mat_shuffled = mat_orig( shuffIdx(:), : );

Recursively divide a square field - Matlab crashes

I am working with simulation of wireless sensor networks in matlab.
I have a 200*200 by field in which 100 sensor nodes have been plotted randomly. Each node has an associated load value with it. I have to place charging stations in this field. I am trying to divide this square recursively as long as I do not found a small sub-square in which I can place only one charging station. Here is the code I wrote to divide the square recursively and count number of stations that can be placed in a subsquare:
%Inputs to the function
%numstations - No. of stations to be placed = 10
%boundCoords - A 2*2 matrix with min and max coordinates of square . e.g [0 0;200 200]
% sensors - A 100*3 matrix for nodes with 1st column as randomly generated 100 x-coordinates,
%second column as randomly generated 100 y-coordinates,
%third column as corresponding load of each node (can be random)
function stationPoss = deploy(numStations, boundCoords)
global sensors;
centerCoord = mean(boundCoords, 1);
numSensors = size(sensors, 1);
sumQuadLoad = zeros(1, 4);
for i = 1:numSensors
if sensors(i, 1) < boundCoords(2, 1) && sensors(i, 2) < boundCoords(2, 2)...
&& sensors(i, 1) > boundCoords(1, 1) && sensors(i, 2) > boundCoords(1, 2)
isIn34Quads = sensors(i, 1) > centerCoord(1); % N
isIn24Quads = sensors(i, 2) > centerCoord(2);
biQuadIndex = [isIn34Quads, isIn24Quads];
quadIndex = bi2de(biQuadIndex) + 1;
sumQuadLoad(quadIndex) = sumQuadLoad(quadIndex) + sensors(i, 3);
end
end
if numStations == 1
[maxQuadLoad, quad] = max(sumQuadLoad); %#ok<ASGLU>
delta = (centerCoord - boundCoords(1, :)) .* de2bi(quad - 1);
assoQuadCoords = [boundCoords(1, :); centerCoord] + repmat(delta, 2, 1);
stationPoss = mean(assoQuadCoords, 1);
else
sumLoad = sum(sumQuadLoad);
quadNumStations = zeros(1, 4);
for i = 1:3
if sumQuadLoad(i) == 0
quadNumStations(i) = 0;
else
quadNumStations(i) = floor(numStations * sumQuadLoad(i) / sumLoad);
end
end
quadNumStations(4) = numStations - sum(quadNumStations);
stationPoss = zeros(numStations, 2);
for i = 1:4
delta = (centerCoord - boundCoords(1, :)) .* de2bi(i - 1);
newBoundCoords = [boundCoords(1, :); centerCoord] + repmat(delta, 2, 1);
if quadNumStations(i) ~= 0
indexRange = sum(quadNumStations(1:i-1)) + (1:quadNumStations(i));
stationPoss(indexRange, :) = deploy(quadNumStations(i), newBoundCoords);
end
end
end
The problem is while trying to run this code with numStations=2 it works fine and with numStations=3 it sometimes crashes. For numStation > 3 it almost always crashes.
I tried to come up with a non-recursive way to write this function but wasn't able to.
Will anyone please help me to figure out the crash problem or in writing non recursive solution to the above function. I have already tried increasing the recursion limit.

Sum of Absolute differences between images in Matlab

I want to implement sum of absolute difference in Matlab to establish a similarity metric between between one video frame and 5 frames either side of this frame (i.e. past and future frames). I only need the SAD value for the co-located pixel in each frame, rather than a full search routine, such as full search.
Obviously I could implement this as nested loops such as:
bs = 2; % block size
for (z_i = -bs:1:bs)
for (z_j = -bs:1:bs)
I1(1+bs:end-bs,1+bs:end-bs) = F1(1+bs+z_i:end-bs+z_i, 1+bs+z_j:end-bs+z_j);
I2(1+bs:end-bs,1+bs:end-bs) = F2(1+bs+z_i:end-bs+z_i, 1+bs+z_j:end-bs+z_j);
sad(:,:) = sad(:,:) + abs( I1(:,:) - I2(:,:));
end
end
However I'm wondering is there a more efficient way of doing it than this? At the very least I guess I should define the above code snippet as a function?
Any recommendations would be grateful accepted!
You should use the command im2col in MATLAB you will be able to do so in Vectorized manner.
Just arrange each neighborhood in columns (For each frame).
Put them in 3D Matrix and apply you operation on the 3rd dimension.
Code Snippet
I used Wikipedia's definition of "Sum of Absolute Differences".
The demo script:
```
% Sum of Absolute Differences Demo
numRows = 10;
numCols = 10;
refBlockRadius = 1;
refBlockLength = (2 * refBlockRadius) + 1;
mImgSrc = randi([0, 255], [numRows, numCols]);
mRefBlock = randi([0, 255], [refBlockLength, refBlockLength]);
mSumAbsDiff = SumAbsoluteDifferences(mImgSrc, mRefBlock);
```
The Function SumAbsoluteDifferences:
```
function [ mSumAbsDiff ] = SumAbsoluteDifferences( mInputImage, mRefBlock )
%UNTITLED2 Summary of this function goes here
% Detailed explanation goes here
numRows = size(mInputImage, 1);
numCols = size(mInputImage, 2);
blockLength = size(mRefBlock, 1);
blockRadius = (blockLength - 1) / 2;
mInputImagePadded = padarray(mInputImage, [blockRadius, blockRadius], 'replicate', 'both');
mBlockCol = im2col(mInputImagePadded, [blockLength, blockLength], 'sliding');
mSumAbsDiff = sum(abs(bsxfun(#minus, mBlockCol, mRefBlock(:))));
mSumAbsDiff = col2im(mSumAbsDiff, [blockLength, blockLength], [(numRows + blockLength - 1), (numCols + blockLength - 1)]);
end
```
Enjoy...

Evolution strategy with individual stepsizes

I'm trying to find a good solution with an evolution strategy for a 30 dimensional minimization problem. Now I have developed with success a simple (1,1) ES and also a self-adaptive (1,lambda) ES with one step size.
The next step is to create a (1,lambda) ES with individual stepsizes per dimension. The problem is that my MATLAB code doesn't work yet. I'm testing on the sphere objective function:
function f = sphere(x)
f = sum(x.^2);
end
The plotted results of the ES with one step size vs. the one with individual stepsizes:
The blue line is the performance of the ES with individual step sizes and the red one is for the ES with one step size.
The code for the (1,lambda) ES with multiple stepsizes:
% Strategy parameters
tau = 1 / sqrt(2 * sqrt(N));
tau_prime = 1 / sqrt(2 * N);
lambda = 10;
% Initialize
xp = (ub - lb) .* rand(N, 1) + lb;
sigmap = (ub - lb) / (3 * sqrt(N));
fp = feval(fitnessfct, xp');
evalcount = 1;
% Evolution cycle
while evalcount <= stopeval
% Generate offsprings and evaluate
for i = 1 : lambda
rand_scalar = randn();
for j = 1 : N
Osigma(j,i) = sigmap(j) .* exp(tau_prime * rand_scalar + tau * randn());
end
O(:,i) = xp + Osigma(:,i) .* rand(N,1);
fo(i) = feval(fitnessfct, O(:,i)');
end
evalcount = evalcount + lambda;
% Select best
[~, sortindex] = sort(fo);
xp = O(:,sortindex(1));
fp = fo(sortindex(1));
sigmap = Osigma(:,sortindex(1));
end
Does anybody see the problem?
Your mutations have a bias: they can only ever increase the parameters, never decrease them. sigmap is a vector of (scaled) upper minus lower bounds: all positive. exp(...) is always positive. Therefore the elements of Osigma are always positive. Then your change is Osigma .* rand(N,1), and rand(N,1) is also always positive.
Did you perhaps mean to use randn(N,1) instead of rand(N,1)? With that single-character change, I find that your code optimizes rather than pessimizing :-).