MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Moving through varibles in for loop (ugly)...

Asked by Chris E. on 19 Jul 2013

Hello everyone,

Well I have an issue where I have to set some data, I'm a little lost on how to do it, but I made a "cheating" way of doing this... A little background, the data that is coming in sometimes has bad data, it is very noticeable in the plots because the bad points of data show up as the same value over and over, so I devised a way to look through the needed variables and turn the bad data to ether 0 or NaN's so when it plots, we can see the useful information.

So here is the issue, it seems like bad code, sludgy and ugly (maybe its nice, I don't know...). I was hoping for second opinions, advice or help to make it better. If anyone knows how to make it better or how to clean it up then please help me out, I appreciate any help and learning I can get. Here is an example of the code:

```RMSVal = [125.3226  125.3226  339.9060  101.2705  131.3098   71.1203 125.3226  125.3226];
```
```AreaVal = [228.4361  228.4361   33.5430   96.2065   70.9288   30.4743  228.4361  228.4361];
```
```meanVal = [-3.2270   -3.2270   -3.2308   -3.2542   -3.2136   -3.1690   -3.2270   -3.2270];
```
```RMSValStd = [6.8557    6.8557   34.6666    3.4756   11.6483    5.6991    6.8557    6.8557];
```
```AreaValStd = [322.9295  322.9295   77.5901   85.3251  162.5888   63.1066  322.9295  322.9295];
```
```meanValStd = [0.0069    0.0069    0.0244    0.0035    0.0116    0.0057    0.0069    0.0069];
```
```c = 1;
for var = {'RMSVal'; 'AreaVal';  'RMSValStd'; 'AreaValStd'; 'meanVal'; 'meanValStd'}'
nv = var{1};
[amount,vals]=hist(eval(nv),unique(eval(nv)));
rm = vals(amount > 1);
if c <= 4
eval([nv '(' nv '== rm) = 0']) %turns to = 0
else
eval([nv '(' nv '== rm) = NaN']) %turns to =  NaN
end
c = c + 1;
end
```

Thank you!

1 Comment

Cedric Wannaz on 19 Jul 2013

Wouldn't it be enough to check repetitions on one variable only?

Products

No products are associated with this question.

Answer by Cedric Wannaz on 19 Jul 2013
Edited by Cedric Wannaz on 19 Jul 2013

If it is enough to check one variable only and update them all accordingly, one solution could be:

``` dup = ~diff(RMSVal) ;                               % Is duplicated.
if any(dup)
lId = [dup, false] | [false, dup] ;
RMSVal(lId)     = 0 ;
AreaVal(lId)    = 0 ;
meanVal(lId)    = 0 ;
RMSValStd(lId)  = 0 ;
AreaValStd(lId) = NaN ;
meanValStd(lId) = NaN ;
end```

If all data should be checked, but invalid elements in one array invalidate the other arrays too at the same locations (which is not what you have):

``` buffer = [RMSVal; AreaVal; meanVal; RMSValStd; AreaValStd; meanValStd] ;
dup = any(~diff(buffer, 1, 2), 1) ;
if any(dup)
lId = [dup, false] | [false, dup] ;
RMSVal(lId)     = 0 ;
AreaVal(lId)    = 0 ;
meanVal(lId)    = 0 ;
RMSValStd(lId)  = 0 ;
AreaValStd(lId) = NaN ;
meanValStd(lId) = NaN ;
end```

If you want to detect invalid data in each array without "sync'ing" invalid locations:

``` buffer = [RMSVal; AreaVal; meanVal; RMSValStd; AreaValStd; meanValStd] ;
dif = ~diff(buffer, 1, 2) ;
if any(dif(:))
for k = 1 : size(buffer, 1)
if any(dif(k,:))
lId = [dif(k,:), false] | [false, dif(k,:)] ;
if k <= 4
buffer(k,lId) = 0 ;
else
buffer(k,lId) = NaN ;
end
end
end
RMSVal     = buffer(1,:) ;
AreaVal    = buffer(2,:) ;
meanVal    = buffer(3,:) ;
RMSValStd  = buffer(4,:) ;
AreaValStd = buffer(5,:) ;
meanValStd = buffer(6,:) ;
end```

1 Comment

Chris E. on 19 Jul 2013

Thank you for the comments! I think that the last one you suggested will work for what I need and it is faster! Thanks again, Chris