#include "agebandmatrix.h"
#include "agebandmatrixptrvector.h"
#include "mathfunc.h"
#include "doublevector.h"
#include "conversionindex.h"
#include "popinfovector.h"
#include "errorhandler.h"
#include "gadget.h"
#include "global.h"
void AgeBandMatrix::Add(const AgeBandMatrix& Addition, const ConversionIndex &CI, double ratio) {
PopInfo pop;
int minaddage = max(this->minAge(), Addition.minAge());
int maxaddage = min(this->maxAge(), Addition.maxAge());
int age, l, minl, maxl;
if ((maxaddage < minaddage) || (isZero(ratio)))
return;
if (CI.isSameDl()) {
int offset = CI.getOffset();
for (age = minaddage; age <= maxaddage; age++) {
minl = max(this->minLength(age), Addition.minLength(age) + offset);
maxl = min(this->maxLength(age), Addition.maxLength(age) + offset);
for (l = minl; l < maxl; l++) {
pop = Addition[age][l - offset];
pop *= ratio;
(*v[age - minage])[l] += pop;
}
}
} else {
if (CI.isFiner()) {
for (age = minaddage; age <= maxaddage; age++) {
minl = max(this->minLength(age), CI.minPos(Addition.minLength(age)));
maxl = min(this->maxLength(age), CI.maxPos(Addition.maxLength(age) - 1) + 1);
for (l = minl; l < maxl; l++) {
pop = Addition[age][CI.getPos(l)];
pop *= ratio;
pop.N /= CI.getNumPos(l); //JMB CI.getNumPos() should never be zero
(*v[age - minage])[l] += pop;
}
}
} else {
for (age = minaddage; age <= maxaddage; age++) {
minl = max(CI.minPos(this->minLength(age)), Addition.minLength(age));
maxl = min(CI.maxPos(this->maxLength(age) - 1) + 1, Addition.maxLength(age));
if (maxl > minl && CI.getPos(maxl - 1) < this->maxLength(age)
&& CI.getPos(minl) >= this->minLength(age)) {
for (l = minl; l < maxl; l++) {
pop = Addition[age][l];
pop *= ratio;
(*v[age - minage])[CI.getPos(l)] += pop;
}
}
}
}
}
}
void AgeBandMatrix::Subtract(const DoubleVector& Ratio, const ConversionIndex& CI) {
int i, j, j1, j2;
if (CI.isSameDl()) {
int offset = CI.getOffset();
for (i = 0; i < nrow; i++) {
j1 = max(v[i]->minCol(), CI.minLength());
j2 = min(v[i]->maxCol(), CI.maxLength());
for (j = j1; j < j2; j++)
(*v[i])[j] *= Ratio[j - offset];
}
} else {
for (i = 0; i < nrow; i++) {
j1 = max(v[i]->minCol(), CI.minLength());
j2 = min(v[i]->maxCol(), CI.maxLength());
for (j = j1; j < j2; j++)
(*v[i])[j] *= Ratio[CI.getPos(j)];
}
}
}
void AgeBandMatrix::Multiply(const DoubleVector& Ratio) {
int i, j;
for (i = 0; i < nrow; i++)
for (j = v[i]->minCol(); j < v[i]->maxCol(); j++)
(*v[i])[j] *= Ratio[i];
}
void AgeBandMatrix::sumColumns(PopInfoVector& Result) const {
int i, j;
for (i = 0; i < Result.Size(); i++)
Result[i].setToZero();
for (i = 0; i < nrow; i++)
for (j = v[i]->minCol(); j < v[i]->maxCol(); j++)
Result[j] += (*v[i])[j];
}
void AgeBandMatrix::IncrementAge() {
int i, j;
if (nrow <= 1)
return; //only one age
//for the oldest age group
i = nrow - 1;
for (j = v[i]->minCol(); j < v[i]->maxCol(); j++)
(*v[i])[j] += (*v[i - 1])[j];
//for the other age groups
for (i = nrow - 2; i > 0; i--)
for (j = v[i]->minCol(); j < v[i]->maxCol(); j++)
(*v[i])[j] = (*v[i - 1])[j];
//for the youngest age group
for (j = v[0]->minCol(); j < v[0]->maxCol(); j++)
(*v[0])[j].setToZero();
}
void AgeBandMatrix::setToZero() {
int i, j;
for (i = 0; i < nrow; i++)
for (j = v[i]->minCol(); j < v[i]->maxCol(); j++)
(*v[i])[j].setToZero();
}
void AgeBandMatrix::printNumbers(ofstream& outfile) const {
int i, j;
int maxcol = 0;
for (i = 0; i < nrow; i++)
if (v[i]->maxCol() > maxcol)
maxcol = v[i]->maxCol();
for (i = 0; i < nrow; i++) {
outfile << TAB;
for (j = 0; j < v[i]->minCol(); j++)
outfile << setw(smallwidth) << 0.0 << sep;
for (j = v[i]->minCol(); j < v[i]->maxCol(); j++)
outfile << setw(smallwidth) << setprecision(smallprecision) << (*v[i])[j].N << sep;
for (j = v[i]->maxCol(); j < maxcol; j++)
outfile << setw(smallwidth) << 0.0 << sep;
outfile << endl;
}
}
void AgeBandMatrix::printWeights(ofstream& outfile) const {
int i, j;
int maxcol = 0;
for (i = 0; i < nrow; i++)
if (v[i]->maxCol() > maxcol)
maxcol = v[i]->maxCol();
for (i = 0; i < nrow; i++) {
outfile << TAB;
for (j = 0; j < v[i]->minCol(); j++)
outfile << setw(smallwidth) << 0.0 << sep;
for (j = v[i]->minCol(); j < v[i]->maxCol(); j++)
outfile << setw(smallwidth) << setprecision(smallprecision) << (*v[i])[j].W << sep;
for (j = v[i]->maxCol(); j < maxcol; j++)
outfile << setw(smallwidth) << 0.0 << sep;
outfile << endl;
}
}
void AgeBandMatrixPtrVector::Migrate(const DoubleMatrix& MI, PopInfoVector& tmp) {
int i, j, age, length;
for (age = v[0]->minAge(); age <= v[0]->maxAge(); age++) {
for (length = v[0]->minLength(age); length < v[0]->maxLength(age); length++) {
for (j = 0; j < size; j++)
tmp[j].setToZero();
//let tmp[j] keep the population of agelength group on area j after the migration
for (j = 0; j < size; j++)
for (i = 0; i < size; i++)
tmp[j] += (*v[i])[age][length] * MI[j][i];
for (j = 0; j < size; j++)
(*v[j])[age][length] = tmp[j];
}
}
}