Initialization of population for genetic algorithm in matlab - matlab

I randomly generated initial 10 population(let each of size n) of genetic algorithm as follows
for i = 1:10
for j=1:n
population(i,j)=randi([MinIntensity,MaxIntensity]);
end
end
Assume that I have the values of one population.For example let the first population of size 10 is [100 110 120 130 140 150 160 170 180 190].Is it possible to generate the remaining 9 population such that the values are near to the first population?(It is for the quick convergence of genetic algorithm).Also each population is a grayscale image with intensity values represented in row major order.Hence the intensity values should be in the range of 0 - 255.
Please help.Thanks in advance

You can do one thing. Use the first string as it is for the rest of the 9 strings except randomly generate an index (between 1 to n) and assign a random integer only to that positions with that random index.
population(1,:) = [100 110 120 130 140 150 160 170 180 190];
for i = 2:10
idx = randi([1 10]);
population(i,:) = population(1,:);
population(i,idx) = randi([0 255]);
end
With this you will get ten strings differing in only one position.
Edit: Image.
Assuming you have a MXN image. Create a mask for example
randi([-10 10], M , N)
Now add this to your original image. Now you get a new image whose all the pixels are modified but only within the range of -10 to 10. Some of the pixel values might go out of range in that case just modify as below
x(find(x < 0)) = 0 %Here X is your new image.
x(find(x > 255)) = 255

Related

Color some samples of MATLAB figure with different color

I have a discrete signal x of length N traced in MATLAB using the command
stem(abs(x)); axis([0 N+6 0 4]);
The resulted figure is shown below:
My question I need only some values corresponding for example to index [7 10 11 12 15 18 48 50 52 60] to be colored with different color , let's say with red.
How can I do that into my figure ?
Using Multiple Plots by hold on and Matrix Indexing
You could possibly and alternatively place a plot on top of plot by using hold on. This does require an adjustment where you need a vector in this case Sample and Indices which specify the sample number/data point index. You can also use matrix indexing to get the amplitude/data points corresponding to the key point, Indicies.
%Vector relating to the sample/data point number%
Sample = linspace(1,70,70);
%Random test data%
X = randi([0,2],1,70);
stem(Sample,X);
hold on
%Key indices to change colour%
Key_Indices = [7 10 11 12 15 18 48 50 52 60];
%Matrix indexing to get values/amplitudes corresponding to key indices%
X_Prime = X(Key_Indices);
stem(Key_Indices,X_Prime,'r');
axis([0 70 0 3]);
hold off
Ran using MATLAB R2019b
This code makes just the circles red and not the stems
plot with selected red circles
%Vector relating to the sample/data point number
Sample = linspace(1,70,70);
%Random test data
X = randi([0,2],1,70);
stem(Sample,X);
%Key indices to change color
Key_Indices = [7 10 11 12 15 18 48 50 52 60];
line(Sample(Key_Indices), X(Key_Indices), 'linestyle', 'none', 'marker', 'o', 'color', 'r')
axis([0 70 0 3])
grid on

Calculate Interval mean of column in matlab (interval not fixed)

I have an array (2000x2) with two variables and want to calculate the mean of column 2 at intervals determined by column 1. How can i do this?
speed=(:,1); %values range from 0-100 cm/s
press=(:,2);
I want to calculate mean pressure at at 5 cm/s intervals of speed. So that I get 20 values for pressure that correspond to 20 intervals of speed.
Should be simple, but I'm still a beginner in Matlab.
The accumarray function does just that:
data = [0 20 33 44 22 56 25 47 81 90; 3 5 4 3 2 4 5 5 6 0].';
speed = data(:,1);
press = data(:,2);
sz = 5; % interval size
fill = NaN; % fill value in the result, for empty groups
group = floor(speed/sz)+1; % compute index of group for each value
result = accumarray(group, press, [], #mean, NaN); % compute mean of each group

Matlab - finding the values in a vector making a neighborhood chain

I have a vector that has values, say a=[10 20 42 90] and what I am trying to do is to find the neighbors in the range of 30 and replace these values with their means. For example, for the a vector, the value of 20 is a neighbor of 10. Additionally, 42 is also a neighbor of 10 through 20, because it is a neighbor's neighbor but 90 is not a neighboring value and it is not reachable from 10 with a neighborhood size of 30.
So I want to replace all 10, 20 and 42 with their means and obtain the vector a=[24 90].
If a=[10 20 42 66 155], then the resulting vector would be a=[34.5 155].
How do I achieve that?
a=[10 20 42 66 155]; % sample data
r = 30; % sample range
a = accumarray(cumsum([r+1 abs(diff(a))]>r).',a,[],#mean).';
Ungolfed and commented version:
a=[10 20 42 66 155]; % sample data
r = 30; % range
% difference between subsequent groupmembers. First difference is set to be higher than r
d = [r+1 abs(diff(a))];
% each group one label
L = cumsum(d>r);
% calculate mean of each group
a = accumarray(L.',a,[],#mean).';

Creating a cumulative distribution from a vector

I need to create a cumulative distribution from some numbers contained in a vector. The vector counts the number of times a dot product operation occurs in an algorithm I've been given.
An example vector would be
myVector = [100 102 101 99 98 100 101 110 102 101 100 99]
I'd like to plot the probability that I have fewer than 99 dot products, against a range from 0 to 120. The built in function
Cumdist(MyVector)
Isn't appropriate as I need to plot over a wider range than cumdist currently provides.
I've tried using
plot([0 N],cumsum(myVector))
but I have multiple entries which are the same value in my vector, and I can't work out how not to double count.
Here is some python code which does what I want:
count = [x[0] for x in tests]
found = [x[1] for x in tests]
found.sort()
num = Counter(found)
freqs = [x for x in num.values()]
cumsum = [sum(item for item in freqs[0:rank+1]) for rank in xrange(len(freqs))]
normcumsum = [float(x)/numtests for x in cumsum]
tests is a list of numbers representing the number of times a dot product was done.
Here is an example of what I'm looking for:
Example cumulative distribution
To create a cumulative distribution, you cannot use cumsum on the vector directly. Do the following instead:
sortedVector = sort(myVector(:));
indexOfValueChange = [find(diff(sortedVector));true];
relativeCounts = (1:length(sortedVector))/length(sortedVector);
plot(sortedVector(indexOfValueChange),relativeCounts(indexOfValueChange))
EDIT
If your goal is just to modify the x-range of your plot,
xlim([0 120])
should do what you need.
Five hours and an answer already accepted, but if you're still interested in another answer...
What you're trying to do is obtain the empirical CDF of your data. Matlab's Statistics Toolbox, which you likely have, has a function to do exactly this in a statistically careful manner: ecdf. So all you actually need to do is
myVector = [100 102 101 99 98 100 101 110 102 101 100 99];
[Y,X] = ecdf(myVector);
figure;
plot(X,Y);
You can use stairs instead of plot to display the true shape of the empirical distribution.
Here is how I would do it:
myVector = [100 102 101 99 98 100 101 110 102 101 100 99];
N = numel(myVector);
x = sort(myVector);
y = 1:N;
[xplot , idx] = unique(x,'last')
yplot = y(idx)/N
stairs(xplot,yplot)
%Optionally
xfull = [0 xplot 120]
yfull = [0 yplot 1]
stairs(xfull,yfull)

Random sampling from gridded data: How to implement this in Matlab?

I have a 200x200 gridded data points. I want to randomly pick 15 grid points from that grid and replace the values in those grids with values selected from a known distribution shown below. All 15 grid points are assigned random values from the given distribution.
The given distribution is:
Given Distribution
314.52
1232.8
559.93
1541.4
264.2
1170.5
500.97
551.83
842.16
357.3
751.34
583.64
782.54
537.28
210.58
805.27
402.29
872.77
507.83
1595.1
The given distribution is made up from 20 values, which are part of those gridded data points. These 20 grid points are fixed i.e. they must not be part of randomly picking 15 points. The coordinates of these 20 points, which are fixed and should not be part of random picking, are:
x 27 180 154 183 124 146 16 184 138 122 192 39 194 129 115 33 47 65 1 93
y 182 81 52 24 168 11 90 153 133 79 183 25 63 107 161 14 65 2 124 79
Can someone help with how to implement this problem in Matlab?
Building off of my answer to your simpler question, here is a solution for how you can choose 15 random integer points (i.e. subscripted indices into your 200-by-200 matrix) and assign random values drawn from your set of values given above:
mat = [...]; %# Your 200-by-200 matrix
x = [...]; %# Your 20 x coordinates given above
y = [...]; %# Your 20 y coordinates given above
data = [...]; %# Your 20 data values given above
fixedPoints = [x(:) y(:)]; %# Your 20 points in one 20-by-2 matrix
randomPoints = randi(200,[15 2]); %# A 15-by-2 matrix of random integers
isRepeated = ismember(randomPoints,fixedPoints,'rows'); %# Find repeated sets of
%# coordinates
while any(isRepeated)
randomPoints(isRepeated,:) = randi(200,[sum(isRepeated) 2]); %# Create new
%# coordinates
isRepeated(isRepeated) = ismember(randomPoints(isRepeated,:),...
fixedPoints,'rows'); %# Check the new
%# coordinates
end
newValueIndex = randi(20,[1 15]); %# Select 15 random indices into data
linearIndex = sub2ind([200 200],randomPoints(:,1),...
randomPoints(:,2)); %# Get a linear index into mat
mat(linearIndex) = data(newValueIndex); %# Update the 15 points
In the above code I'm assuming that the x coordinates correspond to row indices and the y coordinates correspond to column indices into mat. If it's actually the other way around, swap the second and third inputs to the function SUB2IND.
I think yoda already gave the basic idea. Call randi twice to get the grid coordinate to replace, and then replace it with the appropriate value. Do that 15 times.