MATLAB accessing conditional values and performing operation in single column - matlab

Just started MATLAB 2 days ago and I can't figure out a non-loop method (since I read they were slow/inefficient and MATLAB has better alternatives) to perform a simple task.
I have a matrix of 5 columns and 270 rows. What I want to do is:
if the value of an element in column 5 of matrix goodM is below 90, I want to take that element and and subtract it from 90.
So far I tried:
test = goodM(:,5) <= 90;
goodM(test) = 999;
It changes all goodM values within column 1 not 5 into 999, in addition this method doesn't allow me to perform operations on the elements below 90 in column 5. Any elegant solution to doing this?
edit:: goodM(:,5)(test) = 999; doesn't seem to work either so I have no idea to specify the target column.

I am assuming you are looking to operate on elements that have values below 90 as your text in the question reads, rather than 'below or equal to' as represented by '<=' as used in your code. So try this -
ind = find(goodM(:,5) < 90) %// Find indices in column 5 that have values less than 90
goodM(ind,5) = 90 - goodM(ind,5) %// Operate on those elements using indices obtained from previous step

Try this code:
b=90-a(a(:,5)<90,5);
For example:
a =
265 104 479 13 176
26 110 447 208 144
379 163 179 366 464
301 48 274 391 26
429 374 174 184 297
495 375 312 373 82
465 272 399 447 420
205 170 373 122 84
1 417 63 65 252
271 277 412 113 500
then,
b=90-a(a(:,5)<90,5);
b =
64
8
6

Related

How can I create a not-equally-spaced sequence of numbers in MATLAB?

I want to create a not-equally-spaced sequence of numbers in MATLAB starting from 24 and ending to 511.The Sequence uses 32 and 33 alternately as the increment. Thus, the sequence would be as below : [24 56 89 121 154 186 219 251 284 316 349 381 414 446 479 511] Notice that :
24+32=56
56+33=89
89+32=121
121+33=154
...
I just wonder how to modify my own codes or to write new codes to have the answer. My own codes are below:
t_3233=0;
for k=24:(32+t_3233):511
t_3233
k
if t_3233==1
t_3233=0;
else if t_3233==0
t_3233=1;
end
end
end
In this particular case you can use:
len = 16;
vector = round(linspace(24,511,len))

read/load parts of the irregular file by Matlab

I would like to partly load a PTX file by matlab (please see the following example)
I need to read and write the first two row (2 numbers) into 2 variables say a and b. And read and write the data from 5th row to the end into a matrix
Thanks for your help
114
221
1 0 0
1 0 0 0
-5.566405 -7.161944 -1.144557 0.197208 24 29 35
-5.560656 -7.154540 -1.137673 0.222400 29 32 39
-5.559846 -7.153491 -1.131895 0.254002 37 40 49
-5.560894 -7.154833 -1.126452 0.305013 51 54 63
-5.560084 -7.153783 -1.120633 0.290013 72 76 88
-5.561128 -7.155119 -1.115189 0.243214 105 113 134
-5.563203 -7.157782 -1.109926 0.227604 130 143 177
-5.569191 -7.165479 -1.105504 0.201602 121 140 173
-7.833616 -10.078705 -1.546952 0.130007 94 112 134
Look at the tdfread function in order to get the data into Matlab. It should be something like datafile = tdfread(filename, '\t'). Once you have that, index into the variable returned from that function like
a = datafile(1, 1);
b = datafile(2, 1);
data = datafile(5:end, :);

find peaks and frequency from spectrum

suppose that we have following picture,which represent power spectral picture
my goal is following:
1.detect peak value of this power spectral picture
2.detect at which frequency it was
first of all,i have got this picture from following command
[Pxx,f]=periodogram(B,[],[],100);
plot(f,Pxx);
where B is input signal and 100 is sampling frequency,i have tried to use findpeaks command in matlab ,like this
[pxx_peaks,location]=findpeaks(Pxx);
and then find
f(location)
but it does not seem to fit to actual frequencies,so please tell me how to find frequencies from given peaks?thanks a lot of
example is following :
peaks are following :
0.417543614272817
0.389922187581014
0.381603315802419
0.601652859233616
0.396925294300794
0.369200511917405
0.477076452316346
0.792431584110476
0.612598437936600
0.564751537228850
0.940538666131177
0.600215481734847
0.985881201195063
0.950077461673118
1.24336273213410
1.84522775800633
1.73186592736729
3.46075557122590
4.93259798197976
8.47095716918618
25.2287636895831
1422.19492782494
60.8238733887811
11.3141744831953
8.65598040591953
3.92785491164888
2.51086405960291
2.27469230188760
1.90435488292485
1.25933693517960
1.52851575480462
0.933543409438383
1.21157308704582
0.821400666720535
1.28706199713640
1.19575886464231
0.736744959694641
0.986899895695809
0.758792061180657
0.542782326712391
0.704787750202814
0.998785634315287
0.522384453408780
0.602294251721841
0.525224294805813
0.624034405807298
0.498659616687732
0.656212420735658
0.866037361133916
0.624405636807668
0.435350646037440
1.22960953802959
0.891793067878849
1.06358076764171
1.34921178081181
1.02878577330537
1.93594290806582
1.14486512201656
2.01004088022982
2.24124811810385
2.15636037453584
4.81721425534142
4.87939454466131
10.5783535493504
27.0572221453758
1490.03057130613
62.3527480644562
13.6074209231800
9.85304975304259
16.3163128995995
74.1532966917877
1510.37374385290
27.7825124315786
8.66382951478539
7.72195587189507
6.06702456628919
3.35353608882459
4.90341095941571
5.07665716731356
4.47635486149688
9.79494608790444
22.9153086380666
1119.97978883924
57.0699524267842
15.2791339483160
5.36617545130941
3.90480316969632
2.58828964019220
1.16385064506181
1.55998411282069
1.14803074836796
0.468260146832541
0.467641715366303
0.698088976126660
0.504713663418641
0.375910057283262
0.331115262928959
0.204555648718379
0.182936666944843
0.293075999812128
0.272993318570981
0.280495615619829
0.148399626645134
location :
3
6
8
11
13
16
18
20
22
25
27
30
32
34
37
39
42
44
46
49
51
55
58
61
63
65
68
70
73
75
77
79
82
85
87
89
91
94
96
99
101
103
106
108
111
113
115
118
120
123
125
127
129
132
134
137
139
141
144
146
148
151
153
156
158
162
165
167
171
174
176
179
183
185
188
190
193
195
197
199
202
204
208
211
213
216
218
220
222
225
227
230
232
234
237
239
241
243
245
248
250
252
254
and f(location)
f(location)
ans =
0.3906
0.9766
1.3672
1.9531
2.3438
2.9297
3.3203
3.7109
4.1016
4.6875
5.0781
5.6641
6.0547
6.4453
7.0313
7.4219
8.0078
8.3984
8.7891
9.3750
9.7656
10.5469
11.1328
11.7188
12.1094
12.5000
13.0859
13.4766
14.0625
14.4531
14.8438
15.2344
15.8203
16.4063
16.7969
17.1875
17.5781
18.1641
18.5547
19.1406
19.5313
19.9219
20.5078
20.8984
21.4844
21.8750
22.2656
22.8516
23.2422
23.8281
24.2188
24.6094
25.0000
25.5859
25.9766
26.5625
26.9531
27.3438
27.9297
28.3203
28.7109
29.2969
29.6875
30.2734
30.6641
31.4453
32.0313
32.4219
33.2031
33.7891
34.1797
34.7656
35.5469
35.9375
36.5234
36.9141
37.5000
37.8906
38.2813
38.6719
39.2578
39.6484
40.4297
41.0156
41.4063
41.9922
42.3828
42.7734
43.1641
43.7500
44.1406
44.7266
45.1172
45.5078
46.0938
46.4844
46.8750
47.2656
47.6563
48.2422
48.6328
49.0234
49.4141
this seems to me like findpeaks does exactly what it should if used with no further parameters it
"finds local peaks in the data vector X. A local peak
is defined as a data sample which is either larger than the two
neighboring samples or is equal to Inf."
(http://www.mathworks.de/de/help/signal/ref/findpeaks.html)
since the only check this function does is testing if a point higher then is neighbours you get a lot of points in a noisy signal
you might want to limit the number of peaks findpeaks returns for example findpeaks(Pxx,'NPEAKS',n) only returns the n bigest peaks or findpeaks(X,'THRESHOLD',t) only returns the peaks which are over the threshold t
the best way might be findpeaks(X,'MINPEAKHEIGHT',m) to look for all peaks which are higher than m and determing m as a percentile of your input Pxx

Add a constant value to a vector’s elements

I would like to add a constant value of 360 to a vector of values after the maximum value is reached. That is, if H=[12 26 67 92 167 178 112 98 76 85], how do I write a matlab code so that 180 is added to all values after 178? The answer should be H=[12 26 67 92 167 178 292 278 256 265].
This should work on earlier Matlab versions as well:
H=[12 26 67 92 167 178 112 98 76 85]
[n, n] = max(H);
H(n+1:end) = H(n+1:end) + 180
Try following:
n=find(H==max(H));
H(n+1:end)=H(n+1:end)+180;
Since desired vector values are in increasing order, idea here is to find the index of maximum value and increment all the subsequent elements with 180.
EDIT
Better approach for finding max index, as suggested by #LeonidBeschastny
[~,n]=max(H);

Matlab - Remove bad data from vector of values

I have a vector, stdclock, which holds values that follow this pattern:
stdclock=[13 25 38 50 63 75 88 100 113 125 138 150 163 175 188 200 213 2517 2529 2542 2554 2567 2579 2592 2604 2617 2629 2642 2654 2667 2679 2692 2704 2717]
This data is generated through an encoding of 17 values that come 12 or 13 numbers apart (e.g. 25-13=12, 38-25 = 13, etc). You'll see that the first 17 values follow this pattern. Each group of 17 values encode an object, which we'll call an 'item' and are independent of the subsequent 17 values. Then, between value 17 and 18, there's a much larger difference than 12 or 13, but it could be any number higher than, say, 15. This difference represents a separation qualitative separation in the data such that the first 17 values encode one item, the next 17 values encode another item, etc etc. The difference between the 17th and 18th value will never be as small as 12 or 13. Therefore, I can check for any values >= 15, and be sure that I can separate my data in this way. Alternatively, I can reshape the vector as a 17xlength(stdclock)/17 matrix.
So far so good. The problem is that this vector is generated through hardware which can sometimes have errors such that one or more values is simply dropped and not recorded. I want to figure out an algorithm that will detect that values are missing from an 'item' and then remove all remaining values from that item.
I can't quite wrap my head around how to do this in a way that will work for all patterns of errors (e.g. if an item can have missing numbers anywhere, in any pattern, and neighboring items may also have missing numbers anywhere in any pattern, or nowhere).
Any help would be appreciated. An example of a 'corrupted' item would be like this
stdclock=[13 25 38 50 63 75 88 100 113 125 138 150 163 175 188 200 213 2529 2542 2554 2567 2579 2592 2604 2642 2654 2679 2692 2704]
where this stdclock is the same as the one on top, but I went through in the second item and randomly removed numbers, including the first and last numbers.
If you can assume that the difference between consecutive groups is always larger than some threshold, you can use the approach below: identify consecutive groups, and throw out all groups of a length less than 17. It turns out that the threshold for a new group can be set as low as 15, since a missing data point will split a group of 17 into two shorter groups, which will then both be removed.
stdclock=[13 25 38 50 63 75 88 100 113 125 138 150 163 175 188 200 213 2529 2542 2554 2567 2579 2592 2604 2642 2654 2679 2692 2704];
%# a difference of more than groupDelta indicates a new (pseudo-)group
groupDelta = 15;
groupJump = [1 diff(stdclock) > groupDelta];
%# number the groups
groupNumber = cumsum(groupJump);
%# count, for each group, the numbers.
groupCounts = hist(groupNumber,1:groupNumber(end));
%# if a group contains fewer than 17 entries, throw it out
badGroup = find(groupCounts < 17);
stdclock(ismember(groupNumber,badGroup)) = [];
stdclock =
13 25 38 50 63 75 88 100 113 125 138 150 163 175 188 200 213