2

I have a script in Matlab which finds the peaks and valleys of my data set (looks kinda like a squished sine wave), eventually I want to average all of the data between each peak and trough. Here is the script I am working on, but I keep getting errors when I try to even select out the data between each peak and trough to build a matrix of just the data, even before getting to any of the averaging or anything like that. How can i get this script to work and what am I doing wrong? I get errors like:

The following error occurred converting from cell to double:
Error using double
Conversion to double from cell is not possible.

Error in Test (line 72)
             peakAverages(:,j) = {Peakdata((MaxIdx(j):MinIdx(j+1)),:)};

and if I change it to not be a cell array I get the opposite error. The code I am working on is:

for i = 1 : numel (tasknames) %for each test point do the math and find the peaks. tasknames lists the test points. 

  TaskData = cell2mat (task_data(i));

  Peakdata = TaskData(:, 4); %data is in the 4th column of my larger data matrix. 
  [Maxima, MaxIdx] = findpeaks (Peakdata, ...
                                'MinPeakHeight', mean (Peakdata), ...
                                'MinPeakDistance', 10);
  Maxima = Peakdata (MaxIdx);        

  Troughdata = 1.01 * max (Peakdata) - Peakdata;
  [Minima, MinIdx] = findpeaks (Troughdata, ...
                                'MinPeakHeight', mean (Troughdata), ...
                                'MinPeakDistance', 10);
  Minima = Peakdata (MinIdx); 

  MinLength = length (MinIdx); 
  MaxLength = length (MaxIdx); 

  %if there is a trough first, I want to take the first peak value
  %index and the second trough value index. Also since there are
  %different numbers of peaks and troughs, I want to make sure that
  %they match in length by always ending on a trough index. 

  %if there is a peak first, or MinIdx is greater than MaxIdx, do
  %normal j = 1 until whichver list of peaks/trouhgs is shorter. 
  if MinIdx(1) < MaxIdx(1)
    if MinLength > MaxLength
      for j = 1 : length (MaxIdx)
        peakAverages(:, j) = {Peakdata((MaxIdx(j) : MinIdx(j + 1)), :)};
      end
    elseif MinLength == MaxLength
      for j = 1 : length (MinIdx)
        peakAverages(:, j) = {Peakdata(MaxIdx(j) : MinIdx(j + 1), :)};
      end
    elseif MinLength < MaxLength
      for j = 1 : length (MinIdx)
        peakAverages(:, j) = {Peakdata(MaxIdx(j) : MinIdx(j + 1), :)};
      end
    end
  else 
    if MinLength > MaxLength
      for j = 1 : length (MaxIdx)
        peakAverages(j, :) = {Peakdata(MaxIdx(j) : MinIdx(j), :)};
      end
    elseif MinLength == MaxLength
      for j = 1 : length (MinIdx)
        peakAverages(:, j) = {Peakdata(MaxIdx(j) : MinIdx(j), :)};
      end
    elseif MinLength < MaxLength
      for j = 1 : length (MinIdx)
        peakAverages(:, j) = {Peakdata(MaxIdx(j) : MinIdx(j), :)};
      end
    end
end
Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
  • 1
    This is the most horribly indented code I've seen in my entire life. Why?? – Tasos Papastylianou Aug 13 '16 at 00:08
  • Sorry, was trying to paste it out in a hurry.... – user6711209 Aug 13 '16 at 00:18
  • general advice: 1) When asking a question, ask it via a [Minimal Working Example](http://stackoverflow.com/help/mcve). 2) When writing code, avoid long spaghetti code like this, and think in a top-down way instead, such that the end result reads more like english via properly named functions. This not only helps readability, but isolates bugs more easily. – Tasos Papastylianou Aug 13 '16 at 00:33
  • 1
    as for your error. what is `peakAverages` meant to be? An array of doubles? An array of cells? What's the "opposite error"? What do you expect `{Peakdata(MaxIdx(j) : MinIdx(j + 1), :)}` to return? (i.e. how many elements, and what type) – Tasos Papastylianou Aug 13 '16 at 00:36
  • (just thought I'd clarify what I meant by [top-down design](https://en.wikibooks.org/wiki/A-level_Computing_2009/AQA/Problem_Solving,_Programming,_Data_Representation_and_Practical_Exercise/Problem_Solving/Top-down_design_and_Step-wise_refinement). ) – Tasos Papastylianou Aug 13 '16 at 00:41
  • @TasosPapastylianou I honestly am not sure what it _needs_ to be but what I am trying to get is an array where each cell is columns of data that represent the data points on the downslope between each peak-trough found for each taskname. There always a peak followed by a trough in the data (unless the data collection started halfway between , hence all the if statements) so if there are 20peaks i would expect 20 columns of data for that task name with ~10 data points in each column. basically I want to break up the points that make up the downslope so I can perform functions on them. – user6711209 Aug 13 '16 at 00:45
  • eventually I would like to find the average of each of those downslope columns of data, thats why I called it peakaverages for now. – user6711209 Aug 13 '16 at 00:49

1 Answers1

0

Since you're not keen on creating a minimal working example reproducing the error to put things into context, I made a toy one myself:

% got rid of the for loop - not needed for a minimal example
Peakdata = sin([-50:50]).';
% remaining code is the same.

and I cannot reproduce your error. It just works.
Therefore your bug is in the definition of Peakdata or somewhere before that.

If you feel this is not true, then please provide a more appropriate example. I.e. something that is short (e.g. <10 lines of code) and reproducible, such that I could copy / paste onto my matlab session and run and check the error for myself. Otherwise the answer to your question is "no, it works, the bug is elsewhere".

Tasos Papastylianou
  • 21,371
  • 2
  • 28
  • 57
  • I am not sure how I can without uploading a data file which I cannot do I dont think...I will try and get back shortly. – user6711209 Aug 13 '16 at 01:55
  • Peakdata is a 1210x1 double, I want to use the idx values to section it off, but I keep getting the above error when I try that. – user6711209 Aug 13 '16 at 01:59
  • Also if I try it with your sample data I get the error: Error using double Conversion to double from cell is not possible. – user6711209 Aug 13 '16 at 02:03
  • in that case the code you posted is not the same as the code you're running – Tasos Papastylianou Aug 13 '16 at 02:06
  • Tried it again and it works but I get the wrong output. why does peakAverages come out as a 1x8 cell array. it should only have one entry and in that array is 16 columns of data, since that is how many downslopes there are in that sine plot. – user6711209 Aug 13 '16 at 13:56