Matlab : How to extract elements in a uniform interval? - matlab

I have a (5160 X 4) matrix.
I want to extract just (1,1),(41,1),(81,1),(121,1)........ in a uniform interval, only from the first column of the matrix.

Assuming that data is your matrix, you can do this:
A = data(1:40:5160,1);
The 1:40:5160 will create an array such that it starts at 1, and goes up in increments of 40 as much as possible up until 5160. Once you create 1:40:5160, you can use this array and access the corresponding rows, and you are accessing the first column using the index of 1 for the second parameter. Actually, the last row that gets extracted is 5121. We aren't able to go up to 5161 due to the fact that your matrix has 5160 rows, and we have also specified 5160 as the ending of the indexing.
NB: This is very basic MATLAB syntax. Any standard MATLAB tutorial should teach you this.

Related

Matlab - Generating multiple matrices by looping

I have a vector with +16M data, and I've got to transform it in 101 matrices of 401x401 elements each. I know how to create such matrices independently (writing a loop for each one of them) but I think there must be some way to create all of them in using two or more loops. The problem is, I don't know exactly how to do this.
This is what I've tried so far:
data=load('file.dat');%This file contains 3 columns of data, I only need the first one
var=data(:,1);
p=401;%Size of the matrices
for n=0:400
mat1(n+1,:)=var(p*n+1:p*(n+1),:);
end
This code would create the first 401x401 matrix. By changing the indices, I could (individually) create the rest, but I would prefer to add another loop (or loops) to create them automatically instead of repeating this code a hundred times.
The function 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.
See also the manual entry.

Preserving matrix columns using Matlab brush/select data tool

I'm working with matrices in Matlab which have five columns and several million rows. I'm interested in picking particular groups of this data. Currently I'm doing this using plot3() and the brush/select data tool.
I plot the first three columns of the matrix as X,Y, Z and highlight the matrix region I'm interested in. I then use the brush/select tool's "Create variable" tool to export that region as a new matrix.
The problem is that when I do that, the remaining two columns of the original, bigger matrix are dropped. I understand why- they weren't plotted and hence the figure tool doesn't know about them. I need all five columns of that subregion though in order to continue the processing pipeline.
I'm adding the appropriate 4th and 5th column values to the exported matrix using a horrible nested if loop approach- if columns 1, 2 and 3 match in both the original and exported matrix, attach columns 4/5 of the original matrix to the exported one. It's bad design and agonizingly slow. I know there has to be a Matlab function/trick for this- can anyone help?
Thanks!
This might help:
1. I start with matrix 1 with columns X,Y,Z,A,B
2. Using the brush/select tool, I create a new (subregion) matrix 2 with columns X,Y,Z
3. I then loop through all members of matrix 2 against all members of matrix 1. If X,Y,Z match for a pair of rows, I append A and B
from that row in matrix 1 to the appropriate row in matrix 2.
4. I become very sad as this takes forever and shows my ignorance of Matlab.
If I understand your situation correctly here is a simple way to do it:
Assuming you have a matrix like so: M = [A B C D E] where each letter is a Nx1 vector.
You select a range, this part is not really clear to me, but suppose you can create the following:
idxA,idxB and idxC, that are 1 if they are in the region and 0 otherwise.
Then you can simply use:
M(idxA&idxB&idxC,:)
and you will get the additional two columns as well.

How to change elements in matrices using MATLAB

Starting wish a 7x4 binary matrix I need to change a random bit in each column to simulate error. Have been trying to no avail.
A very straightforward way to do this is to use a for loop. It might not be the most efficient approach in MATLAB, but it's probably good enough considering your data set is so small.
Iterate through each of the four columns. On each iteration, randomly chose a number from 1 to 7 to represent the row in that column that you have selected to change. Finally, flip the bit at that row/column. The following code does just this. Assume that "A" is a binary matrix with 7 rows and 4 columns
for col=1:4; %// Iterate through each column
row = ceil(7*rand()); %// Randomly chose a number from 1 to 7 to represent row
A(row,col) = ~A(row,col); %// Flip the bit at the specified row/col
end
Another possibility is to create 4 random numbers in one call, and assign in a vectorized fashion:
rowNumbers = randi(4,[1 4])
A(rowNumbers,:) = ~A(rowNumbers,:);

Count the number of times a number is repeating in a vector

I have created a vector containing zeros and 1's using the following command in a for loop.
G(:,i)=rand(K,1)<rand;
Since this is part of a larger problem at a particular stage I need to count the number of 1's that are present in each column.
I have tried to find the count using a for loop which is very messy and takes too long.
I found that histc can be used for this but I get an error
histc(G(:,1),1)
First input must be non-sparse numeric array.
Is there a better way to do this or am I missing something here ?
If you have a matrix G containing zeroes and ones, and you want to know how many ones are in each column, all you need is SUM:
nZeroes = sum(G);
This will give you a vector containing a total for each column in G.

What's an appropriate data structure for a matrix with random variable entries?

I'm currently working in an area that is related to simulation and trying to design a data structure that can include random variables within matrices. To motivate this let me say I have the following matrix:
[a b; c d]
I want to find a data structure that will allow for a, b, c, d to either be real numbers or random variables. As an example, let's say that a = 1, b = -1, c = 2 but let d be a normally distributed random variable with mean 0 and standard deviation 1.
The data structure that I have in mind will give no value to d. However, I also want to be able to design a function that can take in the structure, simulate a uniform(0,1), obtain a value for d using an inverse CDF and then spit out an actual matrix.
I have several ideas to do this (all related to the MATLAB icdf function) but would like to know how more experienced programmers would do this. In this application, it's important that the structure is as "lean" as possible since I will be working with very very large matrices and memory will be an issue.
EDIT #1:
Thank you all for the feedback. I have decided to use a cell structure and store random variables as function handles. To save some processing time for large scale applications, I have decided to reference the location of the random variables to save time during the "evaluation" part.
One solution is to create your matrix initially as a cell array containing both numeric values and function handles to functions designed to generate a value for that entry. For your example, you could do the following:
generatorMatrix = {1 -1; 2 #randn};
Then you could create a function that takes a matrix of the above form, evaluates the cells containing function handles, then combines the results with the numeric cell entries to create a numeric matrix to use for further calculations:
function numMatrix = create_matrix(generatorMatrix)
index = cellfun(#(c) isa(c,'function_handle'),... %# Find function handles
generatorMatrix);
generatorMatrix(index) = cellfun(#feval,... %# Evaluate functions
generatorMatrix(index),...
'UniformOutput',false);
numMatrix = cell2mat(generatorMatrix); %# Change from cell to numeric matrix
end
Some additional things you can do would be to use anonymous functions to do more complicated things with built-in functions or create cell entries of varying size. This is illustrated by the following sample matrix, which can be used to create a matrix with the first row containing a 5 followed by 9 ones and the other 9 rows containing a 1 followed by 9 numbers drawn from a uniform distribution between 5 and 10:
generatorMatrix = {5 ones(1,9); ones(9,1) #() 5*rand(9)+5};
And each time this matrix is passed to create_matrix it will create a new 10-by-10 matrix where the 9-by-9 submatrix will contain a different set of random values.
An alternative solution...
If your matrix can be easily broken into blocks of submatrices (as in the second example above) then using a cell array to store numeric values and function handles may be your best option.
However, if the random values are single elements scattered sparsely throughout the entire matrix, then a variation similar to what user57368 suggested may work better. You could store your matrix data in three parts: a numeric matrix with placeholders (such as NaN) where the randomly-generated values will go, an index vector containing linear indices of the positions of the randomly-generated values, and a cell array of the same length as the index vector containing function handles for the functions to be used to generate the random values. To make things easier, you can even store these three pieces of data in a structure.
As an example, the following defines a 3-by-3 matrix with 3 random values stored in indices 2, 4, and 9 and drawn respectively from a normal distribution, a uniform distribution from 5 to 10, and an exponential distribution:
matData = struct('numMatrix',[1 nan 3; nan 2 4; 0 5 nan],...
'randIndex',[2 4 9],...
'randFcns',{{#randn , #() 5*rand+5 , #() -log(rand)/2}});
And you can define a new create_matrix function to easily create a matrix from this data:
function numMatrix = create_matrix(matData)
numMatrix = matData.numMatrix;
numMatrix(matData.randIndex) = cellfun(#feval,matData.randFcns);
end
If you were using NumPy, then masked arrays would be the obvious place to start, but I don't know of any equivalent in MATLAB. Cell arrays might not be compact enough, and if you did use a cell array, then you would have to come up with an efficient way to find the non-real entries and replace them with a sample from the right distribution.
Try using a regular or sparse matrix to hold the real values, and leave it at zero wherever you want a random variable. Then alongside that store a sparse matrix of the same shape whose non-zero entries correspond to the random variables in your matrix. If you want, the value of the entry in the second matrix can be used to indicate which distribution (ie. 1 for uniform, 2 for normal, etc.).
Whenever you want to get a purely real matrix to work with, you iterate over the non-zero values in the second matrix to convert them to samples, and then add that matrix to your first.