preallocation of memory in matlab / octave [closed] - arrays

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I preallocate memory for a large array but the new data appends at the end of the array instead of over writing the data how can I fix this. So I can preallocate memory for a large array.
note the array is 44101x5001 I just used smaller numbers in the example.
Example:
clear all
xfreq=zeros(10,10); %allocate memory
for ww=1:1:10
xfreq_new = xfreq(:,1)+1+ww;
xfreq=[xfreq xfreq_new]; %would like this to over write and append the new data where the preallocated memory of zeros are instead of appending to the end of it.
end
If you run this you'll notice that it appends the ones instead of over writing the zeros.
Aloha
Rick
Hopefully this explains things better
Allocated array
1)Allocated memory of zeros
[0 0 0 0 0
0 0 0 0 0
0 0 0 0 0]
2) Overwriting allocated memory of zeros with a number, the number could be anything not just the number one, I used the number one as an example
[1 0 0 0 0
1 0 0 0 0
1 0 0 0 0]
3) Still Overwriting of allocated memory zeros with a number, the number could be anything not just the number one, I used the number one as an example
[1 1 0 0 0
1 1 0 0 0
1 1 0 0 0]
the problem is with this line
xfreq=[xfreq xfreq_new]; %would like this to over write and append the new data where the preallocated memory of zeros are instead of appending to the end of it.
end

This will work if you want all your entries equal to x
x = (some number)
A = zeros(10,n)
for i=1:n
A(:,i) = x;
end
If you want your columns equal to some other column you have to do
A = zeros(10,n)
for i=1:n
A(:,i) = v;
end
where v is a vector of size (10,1)

Related

How to get data from specific input file format skipping line with scanf [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a .txt file that contains info like this:
9:0
B1 0 0 0 0 0
B2 0 0 0 0 0
B3 4 5 0 0 0
B4 1 2 3 0 0
9:1
B1 0 0 0 0 0
B2 0 0 0 0 0
B3 4 5 0 0 0
B4 1 2 3 0 0
9:2
B1 0 0 0 0 0
B2 0 0 0 0 0
B3 4 5 0 0 0
B4 1 2 3 0 0
(...)
As you can see, the format is a line with the time, and the next four lines is the identifier of "B" followed by five elements of an array.
I can easily read the whole file, looping through the whole file (I know how many lines the file has) using first of all scanf to get the date, next another scanf to read the "B" plus the identifier, and loop four times with scanf again to get the integers of the array and go back to get the time.
This works fine, but (again) as you can see, there's a lot of zeros in the array space, and it would be a lot faster if I check the first element and if it is zero, then skip and read the next box, so I did it and used the break; statement, but the problem is that using break will ruin the structure of my loop, storing in the time variable a B identifier sometimes.
I'm wondering if there's any other way to skip the zeros when I find one, and jump to the next B identifier, i.e. after reading 9:0, i get B1 and then read the first zero, so skip this line and get 'B2' until I find a non-empty array.
If anyone could help me, please!
I think a reasonably fast solution might be to read the entire line into a static char array, skipping to the next line if the 4'th character is 0, and using sscanf to read the values otherwise.
My reasoning here is that the work of fscanf is split between (1) reading in a string from a file, and (2) parsing that string into numbers, and moving them into the provided variables. However, I know IO operations can be pretty slow, so here is another alternative that does slightly less IO.
Use fscanf to read in only the first two tokens of a line (namely, the B_ and the first number), and use fseek to skip to the next line if the first number is 0. I'm not super confident that this will be faster, but its something you could try.

How can I create a new matrix that from the other's elements?

I want to pick out the elements which are
(2*pi*k),
where k=0,1,2,3... which means integer, and fill them (i1) into the other matrix.
But my problem is, I don't know how to make "k" be row. (By the way, dividends and divisors are float, so I need to find the approximations and see them as 2*pi*k).
My code, only can find the elements which are (2*pi*k), but can't order them like if k=1, then it will be put into k=1 row; if k=2, then the element should be put into k=2 row.
For example,
A = [2*pi 6 3 4;0.5*pi 0 2;3.1 7 4 8;2*pi 7 2 9;2.6 4*pi 6*pi 0]
I want the output to be
B = [0 2*pi 4*pi 6*pi;0 2*pi NaN NaN;NaN 2*pi NaN NaN]
This is my code:
k=0;
for m=380:650;
for n=277:600;
if abs((rem(abs(i(m,n)),(2*PI)))-(PI))>=3.11;
k=k+1;
B(m,k)=i1(m,n);
end
end
k=0;
end
It can find what I want but they seem not to be ordered the way I want.
As others, I'm a bit unsure what you want. Here's how I understood it and would code it:
check whether (2*pi*k) is contained in A, you want a numerical approach
output binary result
here's the code:
testPI=#(k) (2*pi*k); %generates 2*pi*k, where k is up to the user
A = [2*pi 6 3 4;0.5*pi 0 2 0;3.1 7 4 8;2*pi 7 2 9;2.6 4*pi 6*pi 0]; %A from example (fixed dimension error)
ismember(A,f(1:10)) %test if k=1:10 is contained in A
ans =
5×4 logical array
1 0 0 0
0 0 0 0
0 0 0 0
1 0 0 0
0 1 1 0
Adapt 1:10 to any value you'd like. Of course this only works if k is within reasonable range, otherwise this approach is suboptimal

Find indices of blocks of 0s that are continuous [duplicate]

This question already has answers here:
Finding islands of zeros in a sequence
(6 answers)
Closed 6 years ago.
I have a vector and I want to find the indices of blocks of 0s that are continuous for at least 3 times.
y = [1 1 1 0 1 1 0 0 0 1 1 1 0 1 0 1 0 0 1 0 0 0 0 1 1];
So in this case, the blocks should be [0 0 0] from 7-9 and [0 0 0 0] from 20-23. The output should give me the indices, something like [7, 9] and [20,23], or even better, change these blocks of 0s to a single NAN to become:
[1 1 1 0 1 1 NAN 1 1 1 0 1 0 1 0 0 1 NAN 1 1]
Thanks!
What you can do is:
Pad the vector with 1 on each side.
Use find and diff to find where the vector changes from 1 to 0 (diff = -1)
Use find and diff to find where the vector changes from 0 to 1 (diff = 1)
Find the duration of each interval by subtracting the values in 3 by the values in 2 (and add 1)
Create a logical vector with true where the duration is >= 3, and use that vector to find the start indices (from the values found in point 2).
Set the value of each of the start indices to NaN
Set the value of start indices + 1 : end indices to [].
And you're set to go!
It actually took a lot more time writing the explanation than it took to write the code. It's quite a nice exercise to learn some basic MATLAB so I'll leave it to you. Good luck!

MATLAB removing rows which has duplicates in sequence

I'm trying to remove the rows which has duplicates in sequence. I have only 2 possible values which are 0 and 1. I have nXm which n shows possible number of bits and m is not important for my question. My goal is to find an matrix which is nX(m-a). The rows a which has the property which includes duplicates in sequence. For example:
My matrix is :
A=[0 1 0 1 0 1;
0 0 0 1 1 1;
0 0 1 0 0 1;
0 1 0 0 1 0;
1 0 0 0 1 0]
I want to remove the rows has t duplicates in sequence for 0. In this question let's assume t is 3. So I want the matrix which:
B=[0 1 0 1 0 1;
0 0 1 0 0 1;
0 1 0 0 1 0]
2nd and 5th rows are removed.
I probably need to use diff.
So you want to remove rows of A that contain at least t zeros in sequence.
How about a single line?
B = A(~any(conv2(1,ones(1,t),2*A-1,'valid')==-t, 2),:);
How this works:
Transform A to bipolar form (2*A-1)
Convolve each row with a sequence of t ones (conv2(...))
Keep only rows for which the convolution does not contain -t (~any(...)). The presence of -t indicates a sequence of t zeros in the corresponding row of A.
To remove rows that contain at least t ones, just change -t to t:
B = A(~any(conv2(1,ones(1,t),2*A-1,'valid')==t, 2),:);
Here is a generalized approach which removes any rows which has given number of consecutive duplicates (not just zero. could be any number).
t = 3;
row_mask = ~any(all(~diff(reshape(im2col(A,[1 t],'sliding'),t,size(A,1),[]))),3);
out = A(row_mask,:)
Sample Run:
>> A
A =
0 1 0 1 0 1
0 0 1 5 5 5 %// consecutive 3 5's
0 0 1 0 0 1
0 1 0 0 1 0
1 1 1 0 0 1 %// consecutive 3 1's
>> out
out =
0 1 0 1 0 1
0 0 1 0 0 1
0 1 0 0 1 0
How about an approach using strings? This is certainly not as fast as Luis Mendo's method where you work directly with the numerical array, but it's thinking a bit outside of the box. The basis of this approach is that I consider each row of A to be a unique string, and I can search each string for occurrences of a string of 0s by regular expressions.
A=[0 1 0 1 0 1;
0 0 0 1 1 1;
0 0 1 0 0 1;
0 1 0 0 1 0;
1 0 0 0 1 0];
t = 3;
B = sprintfc('%s', char('0' + A));
ind = cellfun('isempty', regexp(B, repmat('0', [1 t])));
B(~ind) = [];
B = double(char(B) - '0');
We get:
B =
0 1 0 1 0 1
0 0 1 0 0 1
0 1 0 0 1 0
Explanation
Line 1: Convert each line of the matrix A into a string consisting of 0s and 1s. Each line becomes a cell in a cell array. This uses the undocumented function sprintfc to facilitate this cell array conversion.
Line 2: I use regular expressions to find any occurrences of a string of 0s that is t long. I first use repmat to create a search string that is full of 0s and is t long. After, I determine if each line in this cell array contains this sequence of characters (i.e. 000....). The function regexp helps us perform regular expressions and returns the locations of any matches for each cell in the cell array. Alternatively, you can use the function strfind for more recent versions of MATLAB to speed up the computation, but I chose regexp so that the solution is compatible with most MATLAB distributions out there.
Continuing on, the output of regexp/strfind is a cell array of elements where each cell reports the locations of where we found the particular string. If we have a match, there should be at least one location that is reported at the output, so I check to see if any matches are empty, meaning that these are the rows we don't want to remove. I want to turn this into a logical array for the purposes of removing rows from A, and so this is wrapped with a cellfun call to determine the cells that are empty. Therefore, this line returns a logical array where a 0 means that remove this row and a 1 means that we don't.
Line 3: I take the logical array from Line 2 and invert it because that's what we really want. We use this inverted array to index into the cell array and remove those strings.
Line 4: The output is still a cell array, so I convert it back into a character array, and finally back into a numerical array.

How can I calculate the length of groups of consecutive ones in binary vector? [duplicate]

This question already has answers here:
How to count number of 1 and 0 in the matrix?
(1 answer)
Finding islands of zeros in a sequence
(6 answers)
Closed 7 years ago.
I have a series of binary vectors (time x 1) in which 1s represent a connection between two variables at a given point in time. The connections between the two variables are sporadic, and I would like to know how 'long' each connection between the two variables exists for.
e.g. if the vector for a given set of variables is:
[0 0 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 1 ]
Then I would like to create a new variable which contains the length of contiguous 1s in each instance. From the above example, the new variable would look like this:
[3,1,7]
As the first time that a 1 arose, it was there for 3 consecutive time points, whereas the next time it was only there for 1 time point and finally, the connection was in the data for 7 consecutive time points.
If there is a good way to solve this, I'd love some help.
Cheers
Mac
diff and cumsum give a good pair!
a = [0 0 1 1 1 0 0 0 1 0 0 1 1 1 1 1 1 1 ]
b = cumsum([a 0])
c = diff( [0 b(diff([a 0]) == -1) ] )
%// or
c = diff( [0 b(~(diff([a 0]) + 1)) ] )
c =
3 1 7

Resources