How to reshape a vector to make a matrix? [duplicate] - matlab

This question already has answers here:
Reshaping of Array in MATLAB
(3 answers)
Closed 7 years ago.
Here is what I have:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
And here is what I want to get:
[
1, 2, 3, 4,
5, 6, 7, 8,
9, 10, 11, 12
]
The number of rows and columns (3 and 4 in example) is already known.
How would I do that?

reshape
b = reshape(a, 4, 3)' will would work for your example. Elements are taken from the original and inserted into the new matrix column-wise.
Furthermore, reshape is a built-in MATLAB function. There exists other solutions such as vec2mat that require the communications toolbox.

This guide says
mat = vec2mat(vec,matcol) converts the vector vec into a matrix with matcol columns, creating one row at a time. If the length of vec is not a multiple of matcol, then extra zeros are placed in the last row of mat. The matrix mat has ceil(length(vec)/matcol) rows.

Related

Concatenating a 5x7 matrix with a 1x7 matrix

I am trying to concatenate two matrixes, append_a and new_row. For some reason I can not seem to use brackets:
m5=magic(5)
rm=randi([10 20], 5, 2)
append_a=[m5, rm]
new_row=randi([10 20], 1, 7)

How to access elements of a matrix based on values of a vector

So say I have the below matrix
[1, 2, 3,
4, 5, 6,
7, 8, 9]
And I have a vector [1,3]
I want to access the 1st and 3rd row which would return
[1,2,3
7,8,9]
I need to be able to scale this up to about 1000 rows being grabbed based on values in the vector.
if A is your matrix and v your vector of index, you just have to do A(v,:)

Count the number of non-NaN values in each row of a 2D array

I have a matrix like this:
A = [1, 2, 3, 4, 5, NaN, NaN, NaN, NaN, NaN;
1, 2, 3, 4, 5, 6, 7, NaN, NaN, NaN;
1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
I would like to know how I can count the number of values in each row excluding any NaNs.
So I would get an output like:
output = [5;
7;
10;]
If A is a 2D array, e.g.
A = [1, 2, 3, 4, 5, NaN, NaN, NaN, NaN, NaN;
1, 2, 3, 4, 5, 6, 7, NaN, NaN, NaN;
1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
and you want to count the number of NaN entries on each row of A, you can simply use
>> sum(~isnan(A), 2)
ans =
5
7
10
Breakdown
isnan(A) returns a logical array of the same size as A, in which (logical1 indicates a NaN and 0 a non-NaN.
Note that you have to use the isnan function, here. In particular, the expression A == ~NaN is useless: it would simply return a logical array of the same size as A but full of (logical) 0's. Why? Because, according to floating-point arithmetic, NaN == NaN always returns "false" (i.e. logical 0, in MATLAB).
Then, by applying MATLAB's not operator (~) to that, you get a logical array of the same size as A, in which 1 indicates a non-NaN and 0 a NaN.
Finally, sum(~isnan(A), 2) returns a column vector in which the i-th entry corresponds to the number of logical 1's on the i-th row of ~isnan(A).
The resulting column vector is exactly what you want: a count, row by row, of the non-NaN entries in A.

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)