Set specific elements on a matrix to zero - matlab

I want to preserve some elements in a 36x18x12000 matrix and set everything else to zero. In particular, I'm interested in getting the values of a specific region in the 36x18 map through time. The code I'm trying to use for this is the following:
coflux_SAm(1:26,1:3,:)=0;coflux_SAm(35:36,11:18,:)=0
What I plan to do here is to keep the South American region (lon 27:34 ; lat 4:10 in the map) and delete the rest, basically. I'm getting pretty annoyed of finding that neither this line nor the loop:
for i=1:26
for j=1:3
coflux_SAm(i,j,:)=0;
end
end
for i=35:36
for j=11:18
coflux_SAm(i,j,:)=0;
end
end
are working. They seem to make random modifications in the matrix but I don't even find a pattern to it.

Sorry for the delay in putting the answer here, I just saw that I had to to close the thread. I copy and paste so it can be closed. Cheers
Ok, nevermind...I was obviously being silly and getting worried about the code and not the logic behind what I really wanted. I changed the code to: 'coflux_SAm(1:26,:,:)=0;coflux_SAm(35:36,:,:)=0; coflux_SAm(:,1:3,:)=0;coflux_SAm(:,11:18,:)=0;' and now it works. With the previous one I was deleting the intersection between longitude and latitude and not everything but what I needed...silly me. Thank you anyway if anyone bothered to have a look. Cheers!

Related

matlab - find nearby points of a lot of objects

I have a number of objects that each have three matrices of distance between own points (x1-x1,x1-x2,x1-x3...;x2-x1,x2-x2,x3-x2...) also with y and z.
I want to find as many nearby points as possible, assuming rotation is not an issue.
I tried something. Since Matlab is supposed to work easy with matrices I am sure something is cumbersome but I don't know how to fix it.
For each object and it's mirror, and for each translation on each axes there is an xyz scenario:
(x1,y1,z1;x2,y2,z2;...)
So I am translating and mirroring one object a million times.
for m=1:object1
for n=1:object2
for i=1:NumRows
for j=1:NumRows2
d_x(m,n,i,j)=obj(m).xyz(i,1)-obj(n).xyz(j,1);
d_y(m,n,i,j)=obj(m).xyz(i,2)-obj(n).xyz(j,2);
d_z(m,n,i,j)=obj(m).xyz(i,3)-obj(n).xyz(j,3);
d_r(m,n,i,j)=sqrt(d_x(m,n,i,j)*d_x(m,n,i,j)+d_y(m,n,i,j)*d_y(m,n,i,j)+d_z(m,n,i,j)*d_z(m,n,i,j));
if d_r(m,n,i,j)>=0 & d_r(m,n,i,j)<1.2
d_r(m,n,i,j)=1.2-d_r(m,n,i,j);
else
d_r(m,n,i,j)=0;
end
sy(m,n)=sy(m,n)+d_r(m,n,i,j);
end
end
end
end
Whenever you start putting indices in variable names, think twice if they maybe should be a single variable. Here we have d_x d_y d_z. My recommendation would be to replace them by a single variable:
d_xyz(m,n,i,j,:)=obj(m).xyz(i,:)-obj(n).xyz(j,:);
And now to your next line, what you are calculating there is actually called a 2-norm. If you know the name, it's simple to shorten:
d_r(m,n,i,j) = norm(squeeze(d_xyz(m,n,i,j,:)),2);

matlab - find start and stop of an interesting signal

I have a signal that looks like this :
I would like to find a way to locate the start and end of the portion of the middle.
What I did, is for the values above and below 0.5 to be a constant ==> 1, and if I find many times 1 in the row it means that it's my signal... but it's not a good way I guess! First my "threshold" would not be every time 0.5, and I am sure it exists some better way to do so.
If you guys have some documentations or ideas about that..
Thank you very much.
As mentioned by the others it is more of a DSP question and dsp.stackexchange.com will propably give you a better answer, but until then this might help:
data=csvread('acceleration.txt',1)
threshold_y=max(data)*0.5; %Thanks to GameOfThrows
thershold_x=101; %how many zeros can be between to ones to still count as continuous
addframe=50; %if you want a little bit of data before and after the active area
logic_index=data>threshold_y;
num_index=find(logic_index);
distance=diff(num_index);
gaps=[1 ; find(distance>thershold_x)]; %find the gaps bigger than your threshold
final_index=false(length(data),1);
for i=1:length(gaps)-1 %add ones between
final_index(num_index(gaps(i)+1)-addframe:num_index(gaps(i+1))+addframe)=true;
end
plot(x,data,x,final_index);
it is basically what you decribed in your question but with the addition of dealing with the zeros inbetween an area. thanks to #GameofThrows for the threshold idea.

Finding the first element less than a certain value in an unsorted vector (MATLAB)

Pretty simple, and I thought I knew what I was doing, but apparently not. Anyways.
I need to find the first element in a vector that is less than a specific value. Here is the code that I have been using:
t = 0:0.01:5;
u = ((2)*exp(-10.*t).*cos((4.*sqrt(6)).*t) + ((5)./sqrt(6)).*exp(-10.*t).*sin((4.*sqrt(6)).*t));
for a = 1:size(u)
if u(a) < (0.05)
disp(a)
break
end
end
The value that I'm trying to find is the first element less than 0.05, however, when I run my code, I don't get anything.
What could I be doing wrong?
Thanks!
#user2994291 has correctly pointed out where your loop based solution is going wrong (+1).
However I would also add that what you are trying to do can simply be accomplished by:
find(u < 0.05, 1, 'first')
Technically, the third input is not necessary - you could just use:
find(u < 0.05, 1)
However, I seem to recall reading at some point that find will work faster if you provide the third input.
The upper bound of your for loop is probably equal to 1.
In your case, u is a row vector (can't say 100% for sure in MATLAB as I only have access to GNU Octave right now), but calling size(u) will probably give back [1 501] as an answer. Your for-loop will select 1 as upper bound.
Try replacing size(u) with size(u,2) or, even better, with length(u). I get a = 24 as an answer.
Edit:
from your questions I assume you are a MATLAB beginner, therefore I strongly advise you to look into the built-in debugger (you can add breakpoints by clicking on the left vertical bar next to the desired line of code), this would have helped you identify the error with ease and will save you a lot of time in the future.

Which loops and which co-ordinate system can I use to automate this example of a truss structure

I am completely new to matlab and can't seem to get an if loop to work. For example if Ln > k , plot point i(n-1) to i(n). How would I automatically assign the correct row or column vectors to i(n)?
Here is a diagram of what I'm wanting
What I want to achieve is connect i(0) to i(1) to ... i(n-1) to i(n).
I also am a bit confused at which co-ordinate system to use? I thought it would be easy to use a polar co-ordinate system. Defining a distance and angle from point i(o) and then doing the same from point i(1) but from what I could find, it is necessary to convert back to a cartesian co-ordinate system.
Once I am comfortable with this section I am confident I can take on the next steps, and develop a full solution to my problem. If you are interested in what I am trying to achieve, here's a link
[PLEASE NOTE] In that question I linked to, I was told I made a mess of it. I'm sorry if this question is also not clear. I really have spent the time to make it as clear as possible. I find it hard to express myself sometimes.
For coordinate system, you can use complex numbers as a simple way of working within a 1-D matrix. Otherwise, I'm struggling to understand what you are trying to accomplish. You should at least try to show some code as we will be in a better position to guide you.
There are a bunch of ways you can execute your problem. without getting into details, you do the following:
n = 1
L(1) = ...
point(1) = ...
while (L(n) < k)
n = n+1;
L(n) = L(n-1)*sin(alpha)/sin(alpha+theta);
point(n) = ...
end
plot(point(1:n));

MATLAB runs out of memory during program execution

I have been happily using MATLAB to solve some project Euler problems. Yesterday, I wrote some code to solve one of these problems (14). When I write code containing long loops I always test the code by running it with short loops. If it runs fine and it does what it's supposed to do I assume this will also be the case when the length of the loop is longer.
This assumption turned out to be wrong. While executing the code below, MATLAB ran out of memory somewhere around the 75000th iteration.
c=1;
e=1000000;
for s=c:e
n=s;
t=1;
while n>1
a(s,t)=n;
if mod(n,2) == 0
n=n/2;
else
n=3*n+1;
end
a(s,t+1)=n;
t=t+1;
end
end
What can I do to prevent this from happening? Do I need to clear variables or free up memory somewhere in the process? Will saving the resulting matrix a to the hard drive help?
Here is the solution, staying as close as possible to your code (which is very close, the main difference is that you only need a 1D matrix):
c=1;
e=1000000;
a=zeros(e,1);
for s=c:e
n=s;
t=1;
while n>1
if mod(n,2) == 0
n=n/2;
else
n=3*n+1;
end
t=t+1;
end
a(s)=t;
end
[f g]=max(a);
This takes a few seconds (note the preallocation), and the result g unlocks the Euler 14 door.
Simply put, there's not enough memory to hold the matrix a.
Why are you making a two-dimensional matrix here anyway? You're storing information that you can compute just as fast as looking it up.
There's a much better thing to memoize here.
EDIT: Looking again, you're not even using the stuff you put in that matrix! Why are you bothering to create it?
The code appears to be storing every sequence in a different row of a matrix. The number of columns of that matrix will be equal to the length of the longest sequence currently found. This means that a sequence of two numbers will be padded with a bunch of right hand zeros.
I am sure you can see how this is incredibly inefficient. That may be the point of the exercise, or it will be for you in this implementation.
Better is to keep a variable like "Seed of longest solution found" which would store the seed for the longest solution. I would also keep a "length of longest solution found" keep the length. As you try every new seed, if it wins the title of longest, then update those variables.
This will keep only what you need in memory.
Short Answer:Use a 2d sparse matrix instead.
Long Answer: http://www.mathworks.com/access/helpdesk/help/techdoc/ref/sparse.html