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

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;


final public class MultipathPPM extends MultiPathConvolution{
	public MultipathPPM (Dimension dim, Image img, String problemName){
		super(dim,img,problemName);
	}
	
	
	//==========================================
	//  Parameter initializations
	//------------------------------------------
	protected void initPreconstructor_Variables(){
		initPreconstructorInMPLevel();

		L=2;
		Amax=1;
	    subModel=2;
		tapsSimulationLimit=10000;
        flgDrawNumbers=-1;

		modelDescription[0]="Program2. Model: PPM with ISI, Noise, and Ambient Light. Graph: BER(SNR).";
		modelDescription[2]="       ";
		modelDescription[3]="       "+"Horizontal axis stands for SNR, db.  "+
				                    "Vertical axis stands for log(BER)/log(10).";
		
		
		functionCOUNT=4;
        functionTitle[0]="BER.     SNR=2. Rb=100 MHz";        
        functionTitle[1]="BER,db.  Rb=0.05 Mhz";
        functionTitle[2]="BER,db.  Rb=10 Mhz";
        functionTitle[3]="BER,db.  Rb=100 Mhz";
		
        dmnRangeF=20.0;
        dmnRangeFDown=19.0;
        dmnRangeX=10.0;
        grPoints=20;

        drawGrid=true;
        drawLengenOnCurve=false;
        gridStepY=1.0;
        grStartF=120;
        
    	functionColor=new Color[]{
    			new Color(150,0,0),
    			new Color(0,40,0),
    			new Color(150,0,150),
    			new Color(0,0,255),
    			new Color(255,0,0),
    			new Color(0,0,255)
    	};

	}
	
	//-----------------------------------------------
    // User Input Prompts
    //- - - - - - - - - - - - - - - - - - - - - - - - 
    protected int setParsToStrings(){
         int i=0;
        
         String decription="";
         for(int j=0; j<subModelTitle.length; j++){
        	 decription += ", "+j+" - " + subModelTitle[j];
         }
         
         strParsCrr[i][0]=String.valueOf(subModel);   strParsCrr[i][1]="Sub Model: "+decription; strParsCrr[i++][2]="int"; 
         strParsCrr[i][0]=String.valueOf(shotNoisePresented);   strParsCrr[i][1]="shotNoisePresented, 0 or 1"; strParsCrr[i++][2]="int"; 
         //strParsCrr[i][0]=String.valueOf(SNR);  strParsCrr[i][1]="SNR, dB"; strParsCrr[i++][2]="double"; 
         strParsCrr[i][0]=String.valueOf(amSAR);  strParsCrr[i][1]="SAR, Signal to Ambient Light Ratio"; strParsCrr[i++][2]="double"; 
         strParsCrr[i][0]=String.valueOf(amInterferencePeriodTi);  strParsCrr[i][1]="Ti, Ambient Light Interference Period, sec"; strParsCrr[i++][2]="double"; 
		 strParsCrr[i][0]=String.valueOf(amInteferenceSummationPoints);   strParsCrr[i][1]="NTi, Ambient Light Interf. Sum. Points Numb., 1 for no Interference."; strParsCrr[i++][2]="int";
         
         strParsCrr[i][0]=String.valueOf(dmnRangeX);  strParsCrr[i][1]="Argument Range"; strParsCrr[i++][2]="double"; 
         strParsCrr[i][0]=String.valueOf(dmnRangeF);  strParsCrr[i][1]="Function Range"; strParsCrr[i++][2]="double";
         strParsCrr[i][0]=String.valueOf(dmnStartF);  strParsCrr[i][1]="Function Start"; strParsCrr[i++][2]="double";

         //strParsCrr[i][0]=String.valueOf(Rb);   strParsCrr[i][1]="Bit Rate, Rb"; strParsCrr[i++][2]="double";
         strParsCrr[i][0]=String.valueOf(ceilingHeight);   strParsCrr[i][1]="Room Height, meters"; strParsCrr[i++][2]="double";

         strParsCrr[i][0]=String.valueOf(L);   strParsCrr[i][1]="Maximum symbol length, L"; strParsCrr[i++][2]="int"; 
         strParsCrr[i][0]=String.valueOf(Amax);   strParsCrr[i][1]="Non-zero levels in chip amplitude, A"; strParsCrr[i++][2]="int";
         
         return i;
    }
    public String setParsFromStrings(){
         int i=0;
         try{
        	 subModel =Integer.parseInt(strParsCrr[i][0]);  i++;
        	 shotNoisePresented =Integer.parseInt(strParsCrr[i][0]);  i++;
        	 //SNR =Double.parseDouble(strParsCrr[i][0]);  i++;
        	 amSAR =Double.parseDouble(strParsCrr[i][0]);  i++;
        	 amInterferencePeriodTi = Double.parseDouble(strParsCrr[i][0]);  i++;
        	 amInteferenceSummationPoints = Integer.parseInt(strParsCrr[i][0]);  i++;
        	 
        	 dmnRangeX =Double.parseDouble(strParsCrr[i][0]);  i++;
        	 dmnRangeF =Double.parseDouble(strParsCrr[i][0]);  i++;
        	 dmnStartF =Double.parseDouble(strParsCrr[i][0]);  i++;
        	 //Rb =Double.parseDouble(strParsCrr[i][0]);  i++;
        	 ceilingHeight =Double.parseDouble(strParsCrr[i][0]);  i++;
        	 L =Integer.parseInt(strParsCrr[i][0]);  i++;
        	 Amax =Integer.parseInt(strParsCrr[i][0]);  i++;
         }catch(Exception e){
            return "Exception when (re)setting parameters.\n" + e;    
         }
         return "";
    }
    //- - - - - - - - - - - - - - - - - - - - - - - - 
    // User Input Prompts
	//================================================================
	
	protected void spawnParametersAfterUserApplied(){
		 tapsSimulationLimit=10000;
         simulationBlocked=false;
         userImputCheckOrCorrectionBeforeBasic();
		 if(!simulationBlocked)spanParsInMPLevel();
		 if(!simulationBlocked)userImputCheckOrCorrectionAfterBasic();
		 if(!simulationBlocked)displySpawnedPars();
		 simulateThresholding();
         if(simulationBlocked){
  	  	   for(int i=20; i<modelDescription.length; i++){
  	  		   modelDescription[i]=null;
  	  	   }
		   //Set B to 1.0 to attract attention:
  	  	   BAmb=1.0;
  	  	   con("Simulation blocked.");
         }
	}
	
	private void userImputCheckOrCorrectionBeforeBasic(){
	  	   for(int i=4; i<modelDescription.length; i++){
	  		   modelDescription[i]=null;
	  	   }
           if(L<2){
			   modelDescription[10]="L must be > 1";
			   //Set B to 1.0 to attract attention:
			   simulationBlocked=true;
		   }
	}
	private void userImputCheckOrCorrectionAfterBasic(){
	  	   for(int i=20; i<modelDescription.length; i++){
	  		   modelDescription[i]=null;
	  	   }
		   if(tapsSimulationLimit<=tapsNumber){
			   modelDescription[20]="BER for sub Model " + subModelTitle[subModel]+". Taps Number exceeded limit.";
			   //Set B to 1.0 to attract attention:
			   simulationBlocked=true;
		   }
		   if(2!=subModel){
			   modelDescription[20]="Sub model  " + subModelTitle[subModel]+
			                        " requested, but only " + subModelTitle[subModel]+ 
			                        " is implemented in this window.";
			   //Set B to 1.0 to attract attention:
			   simulationBlocked=true;
		   }
	}
	
	//---------------------------------------------------------
	//To display this strings in graph background: 
	//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
	private void displySpawnedPars(){
	    //con("subModelTile[0]="+subModelTitle[0]+" " + subModel);
		modelDescription[1]="Sub Model = "+subModelTitle[subModel];
		modelDescription[4]="A="+Amax;
		modelDescription[5]="L="+L;
		//modelDescription[6]="SNR="+SNR+",db     SNR="+SN;
		
		modelDescription[7]="Symbols in Alphabet="+aphabetCount;
		modelDescription[8]="M="+M;
		//modelDescription[9]="BitRate, Rb="+Rb+", bits/second.";
		
		modelDescription[10]="Average Length="+avLength;
		modelDescription[11]="Bits per chip="+bitsPerChip;
		//modelDescription[12]="Chip Length="+T+", seconds.";
		modelDescription[13]="Room Height="+ceilingHeight+", meters.";
		modelDescription[14]="Dispersion Length Scale, a="+a+", seconds.";
		modelDescription[15]="Lambda="+lambda;
		
		modelDescription[16]="Recent tapsNumber="+tapsNumber;
    }
	//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
	//  To display this strings in graph background: 
	//------------------------------------------
	//  Parameter initializations
	//==========================================

	
	
	
	//==========================================
	//  Simulation
	//------------------------------------------
    final protected void simulateThresholding(){
       if(simulationBlocked)return;

	   //First, find out number of slots of symbols which  
	   //precede primary symbol and can interfere with primary symbol:
	   int sslots=0;
	   while(sslots*L<tapsNumber)sslots=sslots+1;
	   //Recalculated taps number which fits preceding symbols:
	   int pastTaps=sslots*L;
	   modelDescription[17]="RecentConvolving symbol slots number="+sslots;

	   //Recalculate tapsNumber including primary symbol:
	   int symTapsNumber=pastTaps+L;
	   modelDescription[18]="Recent preceding taps + L ="+symTapsNumber;

       b=new int[symTapsNumber];
	   result=new double[symTapsNumber];
	   //Convolved primary symbol's ambient contribution for each chip: 
	   double[] V=new double[L];
	   
	   int symbol_events=1;
	   for(int i=0; i<sslots; i++){
		   symbol_events=symbol_events*L;
	   }
	
	   //Now, symbol_events=L^sslots
	   int PPMSymbolSimulationLimit=1000000;
	   //Protect against long calculations:
	   if(PPMSymbolSimulationLimit<=symbol_events){
			  modelDescription[20]="BER for sub Model " + subModelTitle[subModel]+
			                       ". Symbol Slots Limit exceeded.";
			  simulationBlocked=true;
			  return;
       }
	   modelDescription[19]="Recent symbol events="+symbol_events;
	   //We are about ready to summarize ...
	   
	   //Variance of J is squrt(2) times more than variance of N:
       //UFun.setHMode(SN/Math.sqrt(2.0), 0==shotNoisePresented);
	   double SNR_PPM=SN/Math.sqrt(2.0);
	   boolean HeavisideMode=0==shotNoisePresented;

	   //Shortcuts:
       double amK=1.0/amSAR;  //Parameter K-declared in [7, Wong, ...]
       double weight_ISI_NOISE=1.0/symbol_events/L/(L-1)/M;

 	   BAmb=0.0; //Full BER
 	   double amInterferenceStep=amInterferencePeriodTi/amInteferenceSummationPoints;
       for(int iXAm=0; iXAm<amInteferenceSummationPoints; iXAm++){
    	    double tt=amInterferenceStep*iXAm;
            double BB=0.0; //BER under integration by time.
            
            //Prepare ambient contributions to current symbol:
            for(int i=0; i<L; i++){
            	V[i]=amK*am_vi(tt+T*i, T);
            }                             
            
            for(int e=0; e<symbol_events; e++){
            	
            	//------------------------------------
            	//Generate symbols and chip sequences.
            	//- - - - - - - - - - - - - - - - - - -
            	int mask=symbol_events;
          	    for(int slot=0; slot<sslots; slot++){
          	    	int sym=mask%L;
          	        mask=(mask-sym)/L;
                    for(int i=0; i<L; i++){
                    	b[slot*L+i]=0;
                        if(sym==i)b[slot*L+i]=Amax;
                    }
          	    }
            	//- - - - - - - - - - - - - - - - - - -
            	//Generate symbols and chip sequences.
            	//------------------------------------

          	    
          	    //Cycle through primary chips:
          	    for(int i=0; i<L; i++){
          	    	//Fill primary symbol's chips with zeros:
          	    	for(int k=0; k<L; k++)b[sslots*L+k]=0;
          	    	//Fill one primary chip "with" non-zero amplitude:
          	    	b[sslots*L+i]=Amax;
          	    	
          	    	//Calculate convolved chips from the top-1 to
              	    //top-L-1 chip which are chips of current symbol:
              	    convolve(pastTaps,b,result,false);
                    //con("e="+e);
          	    	//String debS="";
          	    	//for(int iii=0; iii<result.length; iii++){
          	    	//	debS+=""+result[iii];
          	    	//}
          	    	//con("bh="+debS);
              	    
                    double Zi=lambda*result[pastTaps+i];
                    //con("Zi="+Zi);
                    if(amInteferenceSummationPoints>1)Zi=Zi+V[i];

          	    	//Cycle through competing chips:
              	    for(int j=0; j<L; j++){
          	    	    if(i==j)continue;
                        double Zj=lambda*result[pastTaps+j];
                        //con("Zj="+Zj);
                        if(amInteferenceSummationPoints>1)Zj=Zj+V[j];
                        double G=Zi-Zj;
                        //BB=BB+UFun.erfh(G);
                        BB=BB+UFun.erfh(G*SNR_PPM,HeavisideMode);
                        //con("Binstant="+BB+" G="+G);
              	    }
          	    }
          	    //con("e="+e+"  BB="+BB);
        	} //for(e
            BAmb=BAmb+weight_ISI_NOISE*BB;
            //con("iXAm="+iXAm+"  BB="+BB+"  BAmb="+BAmb);
       } //for(int iXAm=0; 
       
       BAmb=BAmb/amInteferenceSummationPoints;
	   //do1 Wrong way. These values printed before calculations:
       modelDescription[20]="Recent BER "+BAmb;
       con("Recent BER "+BAmb);
	}
	//------------------------------------------
	//  Simulation
	//==========================================
	
	//Accuracy is restricted by 1e-16.
    private double LogBERonSNR(double SNR, double Rb){
		this.SNR=SNR;
		this.Rb=Rb;
		spawnParametersAfterUserApplied();
		//simulateThresholding();
		if(1.0e-16>BAmb)return -16.0; //Blind return. Assumed accuracy limit in Java.
		return Math.log(BAmb)/Math.log(10);
	}
	//Accuracy is restricted by 1e-16.
    private double BERonSNR(double SNR, double Rb){
		this.SNR=SNR;
		this.Rb=Rb;
		spawnParametersAfterUserApplied();
		//simulateThresholding();
		if(1.0e-16>BAmb)return 1.0e-16; //Blind return. Assumed accuracy limit in Java.
		return BAmb;
	}
    //UCFun ftest=new UCFun();	
	protected double functionSwitchX(int fIx, double t) {return 0;}
	protected double functionSwitch(int fIx, double x){
	    switch(fIx){
	    case 1: return LogBERonSNR(x, 0.05E6);
	    case 2: return LogBERonSNR(x, 50.0E6);
	    case 3: return LogBERonSNR(x, 100.0E6);
	    case 0: return BERonSNR(2.0, 100.0E6);
	    }
	    return 0;
    }
}


Copyright (C) 2009 Konstantin Kirillov