Source Code
Infrared Signal Coding Schemes
home top contents previous up next

%Finds P - symbol error probability (symbol error rate)
%for given channel over all chip sequences, all noise events, and all ambient light events.
%It can be speculated that BER=P/M.
%Core algorithm module.
%In this procedure, P is denoted as BAmb.
%
%See main_PAPM_default Test Case for description of input parameters.
function retv=simulatePAPM()

       global a       
       global shotNoisePresented
       %global ambientLightPresented
       global amSAR
       global amInteferenceSummationPoints
       global amInterferencePeriodTi
       global Amax
       global L
       global M
       global SN
       global T
       global S
       global tapsNumber
       global lambda
	   global scaled_chip_length


       %Numerical integration amount:
       NIPoints=100

       
       %-------------------------------------------------
       %Prevent errors:
       %- - - - - - - - - - - - - - - - - - - - - - - - -
       tapsSimulationLimit=10000;          
	   if tapsSimulationLimit<=tapsNumber
		   message='Taps Number limit exceeded.'
           return;
       end
       if L<2 
          message='Incorrect value: L<2.'
          return;
       end   
       %- - - - - - - - - - - - - - - - - - - - - - - - -
       %Prevent errors:
       %-------------------------------------------------

       %Adjust x-scale adopted in MatLab for erfc:
       sqrt2m1=1.0/sqrt(2);

       %First, find out number of preceding symbols:
       sslots=0;
       %We'l try to take enough slots to cover ISI tapsNumber:
	   while sslots*L<tapsNumber
         sslots=sslots+1;
       end  

       %Recalculated taps number occupied by preceding symbols:
       pastTaps=sslots*L;
	   
       %Recalculate tapsNumber including primary symbol:
	   symTapsNumber=pastTaps+L;
       
       b=[1:symTapsNumber];
	   bh=[1:symTapsNumber];
	   %Ambient contribution to primary symbol chips:
	   V=[1:L];

       %Set type of this variable to "float":
       overFlowProtector=1.0;
       
       %-------------------------------------
       %Generate symbols and chip sequences.
       %- - - - - - - - - - - - - - - - - - -
	   AAmax=Amax;  %Number of active levels.
	   %For PAM Amax+1.
   	   overFlowProtector=1.0*L*AAmax;
	   if overFlowProtector>2.0E9
		  sprintf(' L*AAmax>2E9, ~ 32 bit limit.');
          L
          AAmax
          return;
	   end

	   symSlotWeight=L*AAmax;
       
       %Find out number of all combinations of preceding symbols:
       symbol_events=1;
   	   overFlowProtector=1.0; 
	   for i=1:sslots 
   		   overFlowProtector=overFlowProtector*symSlotWeight;
		   if overFlowProtector>2.0E9
  		      sprintf('symSlotWeight^preSymbolSlots>2E9, ~ 32 bit limit.');
              L
              AAmax
              preSymbolSlots
              return;
		   end
		   symbol_events=symbol_events*symSlotWeight; %NewForPAPM
	   end

       %Now, symbol_events=L^sslots
       %We don't know at the moment which limit to take:
       %Take it from a cloud now:
	   PPMSymbolSimulationLimit=1000000;
	   %Protect against long calculations:
	   if PPMSymbolSimulationLimit<=symbol_events
		  sprintf('Symbol Slots Limit exceeded.');
          symbol_events
          PPMSymbolSimulationLimit
		  return;
       end
       %- - - - - - - - - - - - - - - - - - -
       %Generate symbols and chip sequences.
       %-------------------------------------
     
       %Shortcuts:
       amK=1.0/amSAR;  %Parameter K-declared in [7, Wong, ...]

       %%%KVK.Fix1. Please note (L-1) removed. Apparently was a mistake.
       %weight_ISI_NOISE=1.0/symbol_events/L/(L-1);
       weight_ISI_NOISE=1.0/symbol_events/(symSlotWeight*M); %NewForPAPM

       %Prepare constants for numerical integration:
       GaussNorm=1.0/sqrt(2.0*pi); %NewForPAPM

       
       BAmb=0.0;
 	   amInterferenceStep=amInterferencePeriodTi/amInteferenceSummationPoints;
       for iXAm=0:amInteferenceSummationPoints-1

    	    tt=amInterferenceStep*iXAm;
            BB=0.0; %"BER under integration sign" by time.

            %Prepare ambient contributions to current symbol:
            for i=0:L-1
            	V(i+1)=amK*am_vi(tt+T*i, T);
            end                          


            for e=0:symbol_events-1
            
                %-------------------------------------
            	%Generate symbols and chip sequences.
            	%- - - - - - - - - - - - - - - - - - -
            	%
            	%   Symbol is encoded as couple
            	%          (d,A) = (PostionOfPrimaryChip, AmplitudeLevelOfPrimaryChip).
            	%   0<=d<=L-1, 0<A<=Amax
            	%
            	%   (d,A) is encoded as number sym:
            	%   sym=d*Amax+(A-1)
            	%
            	%   Hence, sym has range 0<=sym<symSlotWeight=L*Amax.
                %   In turn, for sequence of Lps symbols, the full number      
            	%   of possible sequences is
            	%
            	%   symbol_events = Lps ^ symSlotWeight 
            	%
            	%   Notations in program:
            	%     preSymbolSlots=Lps
            	%     primaryChip=d
            	%
            	mask=symbol_events;
          	    for slot=0:sslots-1
          	    	%sym=rem(mask,L);
                    sym=rem(mask,symSlotWeight); %NewForPAPM
          	        mask=mask-sym;
                    mask=mask/L;
                    
                    %NewForPAPM
                    amplitude=rem(sym,L);
          	        primaryChip=(sym-amplitude)/L;
          	        amplitude=amplitude+1;

                    for i=0:L-1
                    	b(slot*L+i+1)=0;
                        %Bug discovered:
                        %Was:
                        %if sym==i 
                        %After bug fix:
                        if primaryChip==i
                        %
                           b(slot*L+i+1)=amplitude; %NewForPAPM
                        end   
                    end
          	    end
            	%- - - - - - - - - - - - - - - - - - -
            	%Generate symbols and chip sequences.
            	%-------------------------------------

          	    %Cycle through primary chips:
          	    for i=0:L-1
                    %Fill primary symbol's chips with zeros:
          	    	for k=0:L-1
                      b(sslots*L+k+1)=0;
                    end  
                    
                    for ia=1:Amax

                        %Make i-th primary chip non-zero:
          	    	    %b(sslots*L+i+1)=Amax;
                        b(sslots*L+i+1)=ia;  %NewForPAPM
        
                    
                        %Calculate convolved chips for primary symbol:
                        %from pastTaps+1 to pastTaps+L:
              	        bh=convolve(pastTaps+1,b,bh);

                        Zi=lambda*bh(pastTaps+i+1);
                    
                        if amInteferenceSummationPoints>1 
                           Zi=Zi+V(i+1);
                        end   
                    
                        %NewForPAPM %%%%%%%%%%%%%%%%%%%%%%%%%%%%
                        Gplus=lambda*(ia+0.5)-Zi;
                        Gminus=lambda*(ia-0.5)-Zi;
                        %Setup integration over y.
                    
                        skipSummation = false;
                        normedGplus=0.0;
                        normedGminus=0.0;
                        %We have no processor power to integrate numerically.
                        %Deploy tricks ... 
                        if ~shotNoisePresented
                    	     if Gplus<0.0 || Gminus>0.0 
                                 skipSummation=true;
                             end    
                        else
                    	     normedGplus=Gplus*SN;
                    	     normedGminus=Gminus*SN;
                             
                             %-- Fix3Sept14 -----------------------
                             %Set limits for extreme levels for PAPM:
                             if 1==ia 
                                normedGminus=-100.0;
                             end   
                             if Amax==ia 
                                normedGplus=100.0;
                             end    
                             %Hence, when Amax==1, then limit of integration for
                             %y is -oo to +oo.
                             %-- Fix3Sept14 -----------------------
                             
                    	     normedGplus=min(10.0,normedGplus);
                          	 normedGminus=max(-10.0,normedGminus);
                    	     if normedGplus<-9.0
                                skipSummation=true;
                             end   
                    	     if normedGminus>9.0 
                                skipSummation=true;
                             end   
                    	     %Now, we excluded infinite trunks ...
                        end
                        if skipSummation 
                           continue;
                        end   
                    
                        PSuccess=0.0;
                        %Now, do integrate numerically ...
                        NIStep= (normedGplus-normedGminus)/NIPoints;
                        for iNIy=0:NIPoints-1
                            %Take values in the middle of intervals: add 0.5 to index:
                    	    y=(iNIy+0.5)*NIStep+normedGminus;
                    	    yWeight=GaussNorm*exp(-y*y*0.5)*NIStep;
                            %NewForPAPM %%%%%%%%%%%%%%%%%%%%%%%%%%%%
                            
                            %Cycle through competing chips:
                            PRODUCT=1.0; %NewForPAPM 
                            for j=0:L-1
          	    	            if i==j
                                   continue;
                                end  
                                Zj=lambda*bh(pastTaps+j+1);
                                if amInteferenceSummationPoints>1
                                   Zj=Zj+V(j+1);
                                end
                                G=Zi-Zj;
                                SNRf=sqrt2m1; %SNR factor
                                if ~shotNoisePresented
                                   SNRf=-1;
                                end  
                                %BB=BB+erfh(G,SNRf);
                                %do1 make y unnormed:
                                %arg=y+G*SN
                                qq=max((1-erfh(y+G*SN,SNRf)),0.0);
                                PRODUCT=PRODUCT*qq; %NewForPAPM 
              	            end %Cycle through competing chips
                            PSuccess=PSuccess+yWeight*PRODUCT;  %NewForPAPM 
                        end %Cycle through y-integration    
                        BB=BB+1.0-PSuccess;  %NewForPAPM 
                    end %Cycle through amplitude levels of primary chip.    
                end % Cycle through primary chips: 
                    % for i=0:L-1
            end % for(e
            BAmb=BAmb+weight_ISI_NOISE*BB;
       end % for iXAm=0 ..
       BAmb=BAmb/amInteferenceSummationPoints
       retv=BAmb;
	end

Copyright (C) 2009 Konstantin Kirillov