Filling missing data in a data set - matlab

I have a data set like the following:
x= [1, 4, 10]
y= [10, 20, 30]
(x and y are value pairs, i.e. (1,10), (4,20), (10,30))
I would like to fill the x values gaps and get linear interpolated values for y. The linear interpolation should be done between each value pair, i.e. between (1,10) and (4,20) and then again between (4,20) and (10,30).
x= [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y= [10,?, ?, 20, ?, ?, ?, ?, ?, 30]
How can I solve this with MATLAB?
Regards,
Dennis
P.S. My original data set has over 300 value pairs...

Using interp1
Code:
x= [1, 4, 10];
y= [10, 20, 30];
xi = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
yi = interp1(x,y,xi);
Results:
>> yi
yi =
10 13.333 16.667 20 21.667 23.333 25 26.667 28.333 30
Graphical Output using plot(xi,yi,'-*')

Related

How can I access to the index of a variable in 'for' loop

How do I access the index i and j in a for loop?
mu_1 = [1, 2, 3, 4]
mu_2 = [5, 6, 7, 8]
mu_3 = [9, 10, 11, 12]
mu_4 = [13, 14, 15, 16]
som = 0
for i in range(1, 4):
for j in range(i+1, 5):
r = (mu_i - mu_j)
som = som + r
I want to get this output:
som = ((mu_1 - mu_2) + (mu_1 - mu_3) + (mu_1 - mu_4) +
(mu_2 - mu_3) + (mu_2 - mu_4) +
(mu_3 - mu_4))
I think what you are trying to ask is how to use indices i and j to refer to your mu_n lists. As per the code below, you could add all lists into another list, and index into it.
However, you cannot subtract lists in Python.
Note! : This won't work because the - (subtraction) operation is not supported for list types.
mu = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]]
som = 0
for i in range(4):
for j in range(i+1, 4):
r = (mu[i] - mu[j])
som = som + r
Finally
You might benefit from knowing that indices in Python start from 0.
It is unclear what exactly you are trying to achieve, but you can use the enumerate function to iterate over an iterable together with its indices.
for i, x in enumerate([1, 5, 13, 6]):
# Here, `i` is the items index and `x` the item itself
pass

How to construct a sobel filter for kernel initialization in input layer for images of size 128x128x3?

This is my code for sobel filter:
def init_f(shape, dtype=None):
sobel_x = tf.constant([[-5, -4, 0, 4, 5], [-8, -10, 0, 10, 8], [-10, -20, 0, 20, 10], [-8, -10, 0, 10, 8], [-5, -4, 0, 4, 5]])
ker = np.zeros(shape, dtype)
ker_shape = tf.shape(ker)
kernel = tf.tile(sobel_x, ker_shape)//*Is this correct?*
return kernel
model.add(Conv2D(filters=30, kernel_size=(5,5), kernel_initializer=init_f, strides=(1,1), activation='relu'))
So far I have managed to do this.
But, this gives me error:
Shape must be rank 2 but is rank 4 for 'conv2d_17/Tile' (op: 'Tile') with input shapes: [5,5], [4].
Tensorflow Version: 2.1.0
You're close, but the args to tile don't appear to be correct. That is why you're getting the error "Shape must be rank 2 but is rank 4 for..." You're sobel_x must be a rank 4 tensor, so you need to add two more dimensions. I used reshape in this example.
from tensorflow import keras
import tensorflow as tf
import numpy
def kernelInitializer(shape, dtype=None):
print(shape)
sobel_x = tf.constant(
[
[-5, -4, 0, 4, 5],
[-8, -10, 0, 10, 8],
[-10, -20, 0, 20, 10],
[-8, -10, 0, 10, 8],
[-5, -4, 0, 4, 5]
], dtype=dtype )
#create the missing dims.
sobel_x = tf.reshape(sobel_x, (5, 5, 1, 1))
print(tf.shape(sobel_x))
#tile the last 2 axis to get the expected dims.
sobel_x = tf.tile(sobel_x, (1, 1, shape[-2],shape[-1]))
print(tf.shape(sobel_x))
return sobel_x
x1 = keras.layers.Input((128, 128, 3))
cvl = keras.layers.Conv2D(30, kernel_size=(5,5), kernel_initializer=kernelInitializer, strides=(2,2), activation='relu')
model = keras.Sequential();
model.add(x1)
model.add(cvl)
data = numpy.ones((1, 128, 128, 3))
data[:, 0:64, 0:64, :] = 0
pd = model.predict(data)
print(pd.shape)
d = pd[0, :, :, 0]
for row in d:
for col in row:
m = '0'
if col != 0:
m = 'X'
print(m, end="")
print("")
I looked at using expand_dims instead of reshape but there didn't appear any advantage. broadcast_to seems ideal, but you still have to add the dimensions, so I don't think it was better than tile.
Why 30 filters of the same filter though? Are they going to be changed afterwards?

Group and sum elements that are the same within a vector

Let's say I have a vector that looks as so (the numbers will always be > 0)...
[1, 2, 1, 4, 1, 2, 4, 3]
I need a vectorized implementation that sums the numbers together and uses the original number as the index to store the number. So if I run it I would get...
% step 1
[1+1+1, 2+2, 3, 4+4]
% step 2
[3, 4, 3, 8]
I have already implemented this using for loops, but I feel like there is a vectorized way to achieve this. I am still quite new at vectorizing functions so any help is appreciated.
This sounds like a job for accumarray:
v = [1, 2, 1, 4, 1, 2, 4, 3];
result = accumarray(v(:), v(:)).'
result =
3 4 3 8
Other approaches:
Using histcounts:
x = [1, 2, 1, 4, 1, 2, 4, 3];
u = unique(x);
result = u.*histcounts(x, [u inf]);
Using bsxfun (may be more memory-intensive):
x = [1, 2, 1, 4, 1, 2, 4, 3];
u = unique(x);
result = u .* sum(bsxfun(#eq, x(:), u(:).' ), 1);

Transform matrix without loop

I have oldMat which is a ranking of equity tickers. The column number represents the respective rank, e.g. first column equals highest rank, second column represents second highest rank and so on. The integers within oldMatrepresent the number of the individual equity ticker. The number 3 in oldMat(3,2,1)means, that the third equity ticker is ranked second in the third period (rows represent different periods).
Now, I need to transform oldMat in the following way: The column numbers now represent the individual equity tickers. The integers now represent the rank that individual equity tickers hold at specific periods. For example, the number 2 in newMat(3,3,1) means, that the third equity ticker is ranked second in the third period.
I used a for-loop in order to solve that problem, but I am pretty sure there exists a more efficient way to achieve this result. Here's my code:
% Define oldMat
oldMat(:,:,1) = ...
[NaN, NaN, NaN, NaN, NaN, NaN; ...
1, 3, 4, 6, 2, 5; ...
6, 3, 4, 1, 2, 5; ...
2, 3, 6, 1, 4, 5; ...
5, 4, 6, 2, 3, 1; ...
5, 1, 2, 3, 6, 4; ...
4, 5, 1, 3, 6, 2; ...
4, 1, 6, 5, 2, 3];
oldMat(:,:,2) = ...
[NaN, NaN, NaN, NaN, NaN, NaN; ...
NaN, NaN, NaN, NaN, NaN, NaN; ...
1, 6, 3, 4, 2, 5; ...
6, 3, 2, 1, 4, 5; ...
2, 6, 3, 4, 1, 5; ...
5, 2, 1, 6, 3, 4; ...
5, 1, 3, 6, 2, 4; ...
4, 1, 5, 6, 3, 2];
% Pre-allocate newMat
newMat = nan(size(oldMat));
% Transform oldMat to newMat
for runNum = 1 : size(newMat,3)
for colNum = 1 : size(newMat,2)
for rowNum = 1 : size(newMat,1)
if ~isnan(oldMat(rowNum, colNum, runNum))
newMat(rowNum,oldMat(rowNum, colNum, runNum), runNum) = colNum;
end
end
end
end
Looks like a classic case of sub2ind. You want to create a set of linear indices to access the second dimension of the new matrix and set those equal to the column number. First create a grid of 3D coordinates with meshgrid, then use the oldMat matrix as an index into the second column of the output and set this equal to the column number. Make sure that you don't copy over any NaN values or sub2ind will complain. You can use isnan to help filter these values out for you:
% Initialize new matrix
newMat = nan(size(oldMat));
% Generate a grid of coordinates
[X,Y,Z] = meshgrid(1:size(newMat,2), 1:size(newMat,1), 1:size(newMat,3));
% Find elements that are NaN and remove
mask = isnan(oldMat);
X(mask) = []; Y(mask) = []; Z(mask) = [];
% Set the values now
newMat(sub2ind(size(oldMat), Y, oldMat(~isnan(oldMat)).', Z)) = X;

Derive Matlab value matrix from Matlab key matrix and lookup vector

I have a Matlab object of integer keys in the range 1:1:7 e.g.
[3, 1, 4, 5, 6]
I also have a size 7 vector containing an associated value for each integer key, e.g.
vals = (10, 20, 30, 4000, 50, 60, 70)
what is the most efficient way to create a matrix of the values using the keys as indices, e.g. a matrix
[30, 10, 4000, 50, 60]
(in reality the key object is 6D). Must I loop?
For the case of a 1D matrix a general approach could be:
keys=[3, 1, 4, 5, 6];
vals = [10, 20, 30, 4000, 50, 60, 70]
m=vals(keys)
With this approach you use the values stored in the keys array as indices of the vals array. You can find more information about array insdexing here.
In a more general case in which keys has n rows (3 in the following example):
keys=[3, 1, 4, 5, 6;
1 3 2 4 6 ;
7 6 5 4 3];
vals = [10, 20, 30, 4000, 50, 60, 70]
m=reshape(vals(keys(:)),size(keys))
Hope this helps.
Qapla'
I think this should work. If I got the question.
inds = [3, 1, 4, 5, 6];
vals = inds;
vals(vals==1) = 10;
vals(vals==2) = 20;
vals(vals==3) = 30;
vals(vals==4) = 4000;
vals(vals==5) = 50;
vals(vals==6) = 60;
Is it like that?