/*
* Copyright 2011 JBoss Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.drools.chance.distribution.belief.discrete;
import org.drools.chance.degree.Degree;
import org.drools.chance.distribution.DiscreteProbabilityDistribution;
import org.drools.chance.distribution.Distribution;
import java.util.*;
/**
* TBM
* TODO
* @param <T>
*/
public class TBM<T> implements DiscreteProbabilityDistribution<Set<T>> {
TBM() { }
List<T> singletons = new ArrayList<T>();
Map<BitSet, Degree> massDegreeMap = new HashMap<BitSet, Degree>();
private boolean normalized;
public Degree get( Set<T> values ) {
return getDegree( values );
}
public Degree get( T... values ) {
return getDegree( values );
}
public Degree getDegree( Set<T> values ) {
return massDegreeMap.get( getMask( values ) );
}
public Degree getDegree( T... vals ) {
return massDegreeMap.get(getMask(vals));
}
public void setDegree( Set<T> key, Degree val ) {
massDegreeMap.put( getMask( key ), val );
}
public void setDegree( Degree val, T... key ) {
massDegreeMap.put( getMask( key ), val );
}
protected void setDegree( BitSet key, Degree val ) {
massDegreeMap.put( key, val );
}
public Distribution<Set<T>> getBasicMassAssignment() {
return this;
}
public Distribution<T> toBayesianMassAssignment() {
//TODO
return null;
}
public Degree getMass( T... value ) {
return getMass( getMask( value ) );
}
public Degree getMass( Set<T> value ) {
return getMass( getMask( value ) );
}
public Degree getMass( BitSet value ) {
return massDegreeMap.get( value );
}
public Degree getBelief( T... value ) {
return getBelief( getMask( value ) );
}
public Degree getBelief( Set<T> value ) {
return getBelief( getMask( value ) );
}
public Degree getBelief( BitSet ref ) {
Degree deg = massDegreeMap.values().iterator().next().False();
for ( BitSet set : this.massDegreeMap.keySet() ) {
BitSet test = ref.get(0, size());
test.and(set);
if ( test.cardinality() == set.cardinality() ) {
deg = deg.sum( massDegreeMap.get( set ) );
} else {
}
}
return deg;
}
public Degree getPlausibility( T... value ) {
return getPlausibility( getMask( value ) );
}
public Degree getPlausibility( Set<T> value ) {
return getPlausibility( getMask( value ) );
}
public Degree getPlausibility( BitSet ref ) {
Degree deg = massDegreeMap.values().iterator().next().False();
for ( BitSet set : this.massDegreeMap.keySet() ) {
BitSet test = ref.get(0, size());
if ( test.intersects( set ) ) {
deg = deg.sum( massDegreeMap.get( set ) );
} else {
}
}
return deg;
}
public Degree getCommonality( T... value ) {
return getCommonality( getMask( value ) );
}
public Degree getCommonality( Set<T> value ) {
return getCommonality( getMask( value ) );
}
public Degree getCommonality( BitSet ref ) {
Degree deg = massDegreeMap.values().iterator().next().False();
//TODO
// for ( BitSet set : this.massDegreeMap.keySet() ) {
// BitSet test = ref.get(0, size());
//
// if ( test.intersects( set ) ) {
// deg = deg.sum( massDegreeMap.get( set ) );
// } else {
// }
// }
return deg;
}
public boolean isNormalized() {
return normalized;
}
public void setNormalized(boolean normalized) {
this.normalized = normalized;
}
public Number domainSize(){
return Math.pow(2, singletons.size());
}
public Number universeSize(){
return singletons.size();
}
public Set<Set<T>> getSupport() {
Set<Set<T>> supp = new HashSet<Set<T>>();
for ( BitSet key : massDegreeMap.keySet() ) {
if ( massDegreeMap.get( key ).toBoolean() ) {
supp.add(getSet( key ) );
}
}
return supp;
}
public int size() {
return massDegreeMap.size();
}
public Set<T> universe() {
return new HashSet<T>( singletons );
}
public BitSet universeMask() {
BitSet set = new BitSet( );
set.set( 0, size() );
return set;
}
public Map<BitSet, Degree> getMaskDistribution() {
return massDegreeMap;
}
public Iterator<BitSet> maskIterator() {
return massDegreeMap.keySet().iterator();
}
public Map<Set<T>, Degree> getDistribution() {
Map<Set<T>, Degree> map = new HashMap<Set<T>, Degree>();
for ( BitSet key : massDegreeMap.keySet() ) {
map.put( getSet( key ), massDegreeMap.get( key ) );
}
return map;
}
public Iterator<Set<T>> iterator() {
return getDistribution().keySet().iterator();
}
public BitSet getMask( Set<T> set ) {
BitSet key = new BitSet();
for ( T val : set ) {
key.set(singletons.indexOf(val));
}
return key;
}
public BitSet getMask( T... vals ) {
BitSet key = new BitSet();
for ( T val : vals) {
key.set(singletons.indexOf(val));
}
return key;
}
public Set<T> getSet( BitSet key ) {
Set<T> vals = new HashSet<T>();
for ( int j = 0; j < key.length(); j++ ) {
if ( key.get( j ) ) {
vals.add(singletons.get(j));
}
}
return vals;
}
public void addToDomain( T val ) {
if ( ! singletons.contains( val ) ) {
singletons.add( val );
}
}
public boolean isDiscrete() {
return true;
}
@Override
public String toString() {
return "TBM{" +
"singletons=" + singletons +
", massDegreeMap=" + massDegreeMap +
'}';
}
}