spec/hamiltonian/SoftLocalConnectivityConstraintSpec.js

/* 
	TODO
	
*/


describe("SoftLocalConnectivityConstraint", function() {
  let CPM = require('../../build/artistoo-cjs.js');
  let C
  
  beforeEach(function() {
	  C = new CPM.CPM( [100,100], {T:20})
	  C.add( new CPM.SoftLocalConnectivityConstraint( {
		LAMBDA_CONNECTIVITY : [0,1000]
	  }))
   
  });

/* Testing the parameter checker for this constraint*/
  it("should throw an error when LAMBDA_CONNECTIVITY parameter is not specified", function() {
  	expect(function() {
        C.add( new CPM.SoftLocalConnectivityConstraint({}) );
    }).toThrow("Cannot find parameter LAMBDA_CONNECTIVITY in the conf object!");
  });
  it("should throw an error when NBH_TYPE is set incorrectly", function() {
  	expect(function() {
        C.add( new CPM.SoftLocalConnectivityConstraint({ LAMBDA_CONNECTIVITY : [0,1000], NBH_TYPE : "a" }) );
    }).toThrow("In the SoftLocalConnectivityConstraint, NBH_TYPE must be either 'Neumann' or 'Moore'");
    
    expect(function() {
        C.add( new CPM.SoftLocalConnectivityConstraint({ LAMBDA_CONNECTIVITY : [0,1000], NBH_TYPE : 1}) );
    }).toThrow("In the SoftLocalConnectivityConstraint, NBH_TYPE must be either 'Neumann' or 'Moore'");
    
    expect(function() {
        C.add( new CPM.SoftLocalConnectivityConstraint({ LAMBDA_CONNECTIVITY : [0,1000], NBH_TYPE : [1,2] }) );
    }).toThrow("In the SoftLocalConnectivityConstraint, NBH_TYPE must be either 'Neumann' or 'Moore'");
    
  });

/* Testing the connected components method for specific cases */
  describe("when computing connected components", function() {
  
	it("should return only one component in connected case", function() {
		let nbhobj = {}
		for( let x = 0; x < 5; x++ ){
			nbhobj[ C.grid.p2i([x,3]) ] = true
		}
		expect( C.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(1);
		
	});
	it("should return multiple components in disconnected case", function() {
		let nbhobj = {}
		for( let x = 0; x < 5; x++ ){
			if( x % 2 == 0 ){
				nbhobj[ C.grid.p2i([x,3]) ] = true
			}
		}
		expect( C.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(3);
		
		// diagonal connections don't count as connections
		nbhobj = {}
		for( let x = 0; x < 5; x++ ){
			nbhobj[ C.grid.p2i([x,x]) ] = true
		}
		expect( C.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(5);
		
	});
	it("should listen to the neighborhood type property correctly", function(){
		
		// diagonal connections don't count as connections if the Neumann neighborhood is used (default)
		nbhobj = {}
		for( let x = 0; x < 5; x++ ){
			nbhobj[ C.grid.p2i([x,x]) ] = true
		}
		expect( C.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(5);
	
	
		// ... but this case is connected when the Moore neighborhood is used
		C.getConstraint("SoftLocalConnectivityConstraint").nbhtype = "Moore"
		expect( C.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(1);
		
		// ... and this should be again 5 when we switch back to Neumann
		C.getConstraint("SoftLocalConnectivityConstraint").nbhtype = "Neumann"
		expect( C.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(5);
		
		// Or we can start from scratch:
		let C2 = new CPM.CPM( [100,100], {T:20})
		  C2.add( new CPM.SoftLocalConnectivityConstraint( {
			LAMBDA_CONNECTIVITY : [0,1000],
			NBH_TYPE : "Moore"
		  }))
		expect( C2.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(1);
		
		
	
	
	});	
	it("should listen to the grid torus property correctly", function() {
		let nbhobj = {}
		
		let pix = C.grid.p2i( [0,0] )
		
		// add pixel and its whole neighborhood
		nbhobj[pix] = true
		for( let n of C.grid.neighi(pix) ){
			nbhobj[n] = true
		}
		expect( C.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(1);
		
		// now change torus to false in one or both dimensions while keeping the same nbhobj
		let C_notorus = new CPM.CPM( [100,100], {
			T : 20,
			torus : [false,false]
		  })
		 C_notorus.add( new CPM.SoftLocalConnectivityConstraint( {
			LAMBDA_CONNECTIVITY : [0,1000]
		 }))
		 expect( C_notorus.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(4);
		
		let C_ytorus = new CPM.CPM( [100,100], {
			T : 20,
			torus : [false,true]
		  })
		 C_ytorus.add( new CPM.SoftLocalConnectivityConstraint( {
			LAMBDA_CONNECTIVITY : [0,1000]
		 }))
		 expect( C_ytorus.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(2);
		 
		 let C_xtorus = new CPM.CPM( [100,100], {
			T : 20,
			torus : [true,false]
		  })
		 C_xtorus.add( new CPM.SoftLocalConnectivityConstraint( {
			LAMBDA_CONNECTIVITY : [0,1000]
		 }))
		 expect( C_xtorus.getConstraint("SoftLocalConnectivityConstraint").connectedComponentsOf(nbhobj).length).toEqual(2);

		
	});
  });

/* Testing if the overall constraint works, specific case*/
  describe("when copy attempt would disrupt local connectivity", function() {
  	let src_i, tgt_i, src_type, tgt_type 
  
    beforeEach(function() {
      let cid = C.makeNewCellID(1)
    
      C.setpix( [2,2], cid )
      C.setpix( [3,3], cid )
      C.setpix( [4,4], cid )
      src_i = C.grid.p2i( [2,3] )
      tgt_i = C.grid.p2i( [3,3] )
      src_type = C.pixti( src_i )
      tgt_type = C.pixti( tgt_i )
    });

	it("#checkConnected should return 1", function() {
    	expect(C.getConstraint("SoftLocalConnectivityConstraint").checkConnected( tgt_i, src_type, tgt_type ) ).toEqual(1);
    })
    
    describe("and when LAMBDA_CONNECTIVITY for the tgt celltype", function() {
    	it("is non-zero, constraint should return positive deltaH", function() {
		  expect(C.getConstraint("SoftLocalConnectivityConstraint").deltaH( src_i, tgt_i, src_type, tgt_type ) > 0 ).toBeTruthy();
		}); 
		it("is zero, constraint should return deltaH zero", function() {
		  C.getConstraint("SoftLocalConnectivityConstraint").conf.LAMBDA_CONNECTIVITY[1]=0
		  expect(C.getConstraint("SoftLocalConnectivityConstraint").deltaH( src_i, tgt_i, src_type, tgt_type ) ).toEqual(0);
		}); 
    })

  });

 
});