Search code examples
matlabmatlab-figure

Conditional manipulation of logical numbers


Please I have the following time series { 111110011111000000011000011111} in time interval of seconds. I want to use the following conditions on the sequence.
Assuming the logic (1) = True and (0) = false

if false occurs < 3 seconds and are in between two "true" then it is translated as 1

For instance 11111001111 because the false occurs less than 3 times and is in between ones the zeros is converted to 1. The answer is then 11111111111

if true is < 3 seconds they are translated into 0. for instance, if the 0000001100000, since the ones occur less than 3 times then the answer becomes 0000000000000

The answer for the first example when the condition is applied is

11111111111100000000000011111

I will be grateful if anyone assists me in writing this code MATLAB Thanks in advance

X = [1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1];  % Work with this array.
target = 3;
ind = find(X < target);
disp(ind);
logInd = X < target;

Solution

  • Here is code implementing minimization of (1.00 * EDGES + 0.99 * FP + 0.98 * FN) where FN means a false low/negative and FP a false high/positive.

    The implementation uses the Viterbi decoder approach originally designed for optimal decoding of convolutional codes in a noisy channel. The convolutional coding is replaced by penalizing every 0->1 and 1->0 transition.

    I've named some of the variables in accordance with the application to receiving messages through a noisy link. rxmsg is before the processing takes place, decode is the result of the processing.

    function [best, trellis] = optimize(rules, rxmsg)
        endpoints = repmat(struct('decode', [], 'cost', 0), 2, 1);
        trellis = repmat(endpoints, 1, numel(rxmsg));
        for i = 1:numel(rxmsg)
            % find lowest cost path ending in low (0)
            if endpoints(1).cost < endpoints(2).cost + rules.edgecost
                from = endpoints(1);
                transition = 0;
            else
                from = endpoints(2);
                transition = rules.edgecost;
            end
            lowcost = rules.falsepositivecost * (1 == rxmsg(i));
            next(1) = struct('decode', [from.decode, 0], 'cost', from.cost + transition + lowcost);
            
            % find lowest cost path ending in high (1)
            if endpoints(1).cost + rules.edgecost < endpoints(2).cost
                from = endpoints(1);
                transition = rules.edgecost;
            else
                from = endpoints(2);
                transition = 0;
            end
            highcost = rules.falsenegativecost * (0 == rxmsg(i));
            next(2) = struct('decode', [from.decode, 1], 'cost', from.cost + transition + highcost);
            
            % prepare for next step
            endpoints = next;
            trellis(:, i) = next;
        end
        
        if endpoints(1).cost < endpoints(2).cost
            best = endpoints(1);
        else
            best = endpoints(2);
        end
        best.rxmsg = rxmsg;
    end
    

    Example usage:

    >> rules = struct('edgecost', 1.00, 'falsenegativecost', 0.98, 'falsepositivecost', 0.99);
    >> [best, trellis] = optimize(rules, [1,1,1,1,1,0,0,1,1,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1])
    
    best = 
    
        decode: [1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1]
          cost: 5.9400
         rxmsg: [1 1 1 1 1 0 0 1 1 1 1 1 0 0 0 0 0 0 0 1 1 0 0 0 0 1 1 1 1 1]
    
    
    trellis = 
    
    2x30 struct array with fields:
    
        decode
        cost
    

    I also made a visualizer to see what bits have been changed

    enter image description here

    function display_message_and_decode(rxmsg, decodemsg)
        same = struct('t', [], 'y', []);
        rejected = same;
        corrected = same;
        
        agreemask = (rxmsg == decodemsg);
        for i = 1:numel(agreemask)
            if i > 1
                if agreemask(i-1) && agreemask(i)
                    same.t = [same.t, NaN, i-1, i-.9];
                    same.y = [same.y, NaN, rxmsg(i-1), rxmsg(i)];
                else
                    rejected.t = [rejected.t, NaN, i-1, i-.9];
                    rejected.y = [rejected.y, NaN, rxmsg(i-1), rxmsg(i)];
                    corrected.t = [corrected.t, NaN, i-1, i-.9];
                    corrected.y = [corrected.y, NaN, decodemsg(i-1), decodemsg(i)];
                end
            end
            
            if agreemask(i)
                same.t = [same.t, NaN, i-.9, i];
                same.y = [same.y, NaN, rxmsg(i), rxmsg(i)];
            else
                rejected.t = [rejected.t, NaN, i-.9, i];
                rejected.y = [rejected.y, NaN, rxmsg(i), rxmsg(i)];
                corrected.t = [corrected.t, NaN, i-.9, i];
                corrected.y = [corrected.y, NaN, decodemsg(i), decodemsg(i)];
            end
        end
        
        handles = plot(same.t, same.y, 'k-', rejected.t, rejected.y, 'r-', corrected.t, corrected.y, 'g-', 'LineWidth', 1);
        set(handles(1), 'LineWidth', 4);
        set(gca, 'YLim', [-.2 1.2]);
    end
    

    Here are results from some of the test cases discussed in comments:

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    • Note the last three generated different results than your clarifying comment suggested. Here is a function that will calculate the cost for any proposed solution you think is a better outcome:

      function result = score(rules, rxmsg, decodemsg)
          result = rules.edgecost * sum(abs(diff(decodemsg))) ...
              + rules.falsenegativecost * sum(decodemsg & ~rxmsg) ...
              + rules.falsepositivecost * sum(rxmsg & ~decodemsg);
      end