net.sourceforge.jabm.init.ProportionalCombiAgentInitialiser.java Source code

Java tutorial

Introduction

Here is the source code for net.sourceforge.jabm.init.ProportionalCombiAgentInitialiser.java

Source

/*
 * JABM - Java Agent-Based Modeling Toolkit
 * Copyright (C) 2013 Steve Phelps
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 3 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 */
package net.sourceforge.jabm.init;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import net.sourceforge.jabm.Population;
import net.sourceforge.jabm.agent.Agent;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Required;

public class ProportionalCombiAgentInitialiser implements AgentInitialiser, Serializable, InitializingBean {

    protected float[] proportions;

    protected List<AgentInitialiser> initialisers;

    public ProportionalCombiAgentInitialiser(float[] proportions, List<AgentInitialiser> initialisers) {
        this();
        this.proportions = proportions;
        this.initialisers = initialisers;
    }

    public ProportionalCombiAgentInitialiser() {
        super();
    }

    public void initialise(Population population) {
        Collection<Agent> agents = population.getAgents();
        int total = agents.size();
        Iterator<Agent> agentIterator = agents.iterator();
        for (int p = 0; p < proportions.length; p++) {
            float proportion = proportions[p];
            AgentInitialiser subInitialiser = initialisers.get(p);
            int n = Math.round(proportion * total);
            Population subPopulation = new Population();
            for (int i = 0; i < n; i++) {
                Agent agent = agentIterator.next();
                subPopulation.add(agent);
                subInitialiser.initialise(subPopulation);
            }
        }
    }

    public float[] getProportions() {
        return proportions;
    }

    @Required
    public void setProportions(float[] proportions) {
        this.proportions = proportions;
    }

    public List<AgentInitialiser> getInitialisers() {
        return initialisers;
    }

    @Required
    public void setInitialisers(List<AgentInitialiser> initialisers) {
        this.initialisers = initialisers;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (initialisers.size() == proportions.length + 1) {
            inferMissingProportion();
        }
        if (!(initialisers.size() == proportions.length)) {
            throw new RuntimeException("Proportion/initialisers size mismatch");
        }
        checkSumToOne();
    }

    public void inferMissingProportion() {
        float[] shortProportions = this.proportions;
        int n = shortProportions.length;
        this.proportions = Arrays.copyOf(shortProportions, n + 1);
        float sigma = 0;
        for (int i = 0; i < n; i++) {
            sigma += shortProportions[i];
        }
        this.proportions[n] = 1 - sigma;
    }

    public void checkSumToOne() {
        float sigma = 0.0f;
        for (int i = 0; i < proportions.length; i++) {
            sigma += proportions[i];
        }
        if ((sigma > 1.00001f) || (sigma < 0)) {
            throw new RuntimeException("Proportions do not sum to 1");
        }
    }

}