internal override void Run(HH hh, List <Person> tu) { if (!IsRunCondMet(hh)) { return; } if (IsEligCondMet(hh, tu)) { Dictionary <byte, bool> persElig = eligCond.GetTUValues(hh, tu); foreach (var elig in persElig) { hh.SetPersonValue(value: elig.Value ? 1 : 0, varIndex: indexOutVar, personIndex: elig.Key); } if (coParResultVar != null) { foreach (var elig in persElig) { hh.SetPersonValue(value: elig.Value ? 1 : 0, varIndex: coParResultVar.index, personIndex: elig.Key); } } } else { hh.SetTUValue(value: 0, varIndex: indexOutVar, tu: tu, addTo: false); if (coParResultVar != null) { hh.SetTUValue(value: 0, varIndex: coParResultVar.index, tu: tu); } } }
private void RunUnitLoop(HH hh, List <Person> tu) { // store the "running" variables (yem_unit, ils_earns_unit), and take the level into account foreach (StoreVar v in vars) { if (v.iteration != NOTAP) { continue; // is handled below } if (hh.GetPersonValue(varIndexCurElig, tu[0].indexInHH) <= 0) { continue; // store only for the (head of the) "currently elig" unit } List <Person> altTU = hh.GetAlternativeTU(v.level, tu, description); // on may consider performance here, but let's first get it right double levVal = v.unitLoopILPar == null?hh.GetTUValue(v.origVar.index, altTU) : v.unitLoopILPar.GetValue(hh, altTU); hh.SetPersonValue(levVal, v.storeVar.index, tu[0].indexInHH); } // store the "on demand" variables (e.g. yem_unit1) - they are stored the same way as for a normal loops (i.e. no level-stuff) foreach (StoreVar v in vars) { if (v.iteration != NOTAP && v.iteration == hh.GetPersonValue(varIndexLoopCounter, 0)) { hh.SetTUValue(hh.GetTUValue(v.origVar.index, tu), v.storeVar.index, tu); } } }
internal override void Run(HH hh, List <Person> tu) // is called for each person in HH, i.e. with individual TU { if (!IsRunCondMet(hh)) { return; // see note on run-cond above } foreach (Default d in defaults) { double val = d.parFormula.GetValue(hh, tu, tu[0]); hh.SetPersonValue(val, d.varSpec.index, tu[0].indexInHH); } }
protected void SetCounter(HH hh, double cnt) { if (hh == null) { infoStore.hhAdmin.GlobalSetVar(varIndexLoopCounter, cnt); // sequential run: set counter for all households } else // parallel run: set counter only for the currently processed household { for (int personIndex = 0; personIndex < hh.GetPersonCount(); ++personIndex) { hh.SetPersonValue(cnt, varIndexLoopCounter, personIndex); } } }
void DoOp(HH hh, List <Person> tu, OpItem oi) { double newVal = 0; if (opTask == OPERAND_TYPE.NEGTOZERO) { newVal = Math.Max(oi.numOperator, 0); } else if (mulAdd == DefPar.Value.ILVAROP_MUL) { newVal = oi.numOperator * oi.numOperand; } else { newVal = oi.numOperator + oi.numOperand; } hh.SetPersonValue(newVal, oi.varOperator.index, tu[0].indexInHH); }
private void InitVar(HH hh, out int nElig) { nElig = 0; foreach (List <Person> tu in hh.GetTUs(eligUnit)) { bool isMet = parEligUnitCond == null ? true : FunInSpineBase.IsCondMetByTU(hh, tu, parEligUnitCond, who); if (isMet) { ++nElig; } hh.SetTUValue(isMet ? 1 : 0, varIndexIsElig, tu); // on TU-level: set isULElig_loopname hh.SetTUValue(isMet ? nElig : 0, varIndexIsEligInIter, tu); // on TU-level: set isEligInIter_loopname } for (int p = 0; p < hh.GetPersonCount(); ++p) { hh.SetPersonValue(nElig, varIndexNElig, p); // on HH-level: set nULElig_loopname } }
protected override double DoFunWork(HH hh, List <Person> tu) { double amountToShare = parShare.GetValue(hh, tu); List <byte> shareBetween = new List <byte>(); if (parShareBetween != null) { shareBetween = (from p in parShareBetween.GetTUValues(hh, tu) where p.Value select p.Key).ToList(); if (shareBetween.Count == 0 && !shareAllIfNoElig) { base.SetOutVars(0, hh, tu); return(0); } } if (shareBetween.Count == 0) { shareBetween = (from p in tu select p.indexInHH).ToList(); } Dictionary <byte, double> pShares = new Dictionary <byte, double>(); double sumShares = 0; if (parShareProp != null) { foreach (var pers in tu) { double share = 0; if (shareBetween.Contains(pers.indexInHH)) { share = parShareProp.GetValue(hh, tu, pers); if (ignoreNegProp && share < 0) { share = 0; } sumShares += share; } pShares.Add(pers.indexInHH, share); } if (sumShares == 0) { if (!shareEquIfZero && amountToShare != 0) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { // only report if there is anything to share isWarning = true, runTimeErrorId = description.funID, message = $"{description.Get()}: HH {infoStore.GetIDHH(hh)}: {parShareProp.xmlValue} is 0 for all eligible persons - equal sharing is applied" }); } pShares.Clear(); } } if (sumShares == 0) { sumShares = shareBetween.Count; foreach (var pers in tu) { pShares.Add(pers.indexInHH, shareBetween.Contains(pers.indexInHH) ? 1 : 0); } } double oneShare = amountToShare / sumShares; foreach (var ps in pShares) { double v = oneShare * ps.Value; hh.SetPersonValue(value: v, varIndex: coParOutVar.Item1.index, personIndex: ps.Key, addTo: coParOutVar.Item2); if (coParResultVar != null) { hh.SetPersonValue(value: v, varIndex: coParResultVar.index, personIndex: ps.Key); } } return(0); }
internal override void Run(HH hh, List <Person> tu) // is called for each person in HH, i.e. with individual TU { if (!IsRunCondMet(hh)) { return; } // 1st step of uprating aggregates: store original values Dictionary <int, List <double> > orParts = new Dictionary <int, List <double> >(); // store the original parts ... Dictionary <int, double> sumParts = new Dictionary <int, double>(); // ... and the actual sum of the parts (which may differ from the aggregate, hopefully not by much) foreach (AggUpVar auv in aggUpVars) { double agg = hh.GetPersonValue(auv.varSpec.index, tu[0].indexInHH); double sumP = 0.0; foreach (VarSpec pv in auv.parts) { double p = hh.GetPersonValue(pv.index, tu[0].indexInHH); sumP += p; if (!orParts.ContainsKey(auv.varSpec.index)) { orParts.Add(auv.varSpec.index, new List <double>()); } orParts[auv.varSpec.index].Add(p); } //sumParts.Add(auv.varSpec.index, sumP); // first thought that this approach is more accurate ... sumParts.Add(auv.varSpec.index, agg); // ... but the old exe uses this if (Math.Abs(agg - sumP) > auv.tolerance) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, runTimeErrorId = description.funID, message = $"{description.Get()}: idperson {infoStore.GetIDPerson(hh, tu[0].indexInHH)}: parts of {auv.varSpec.name} do not sum up {agg} <> {sumP}" }); } } // uprating "normal" variables foreach (UpVar uv in upVars) { if (uv.parCondition == null || // either there is no condition or the condition is fulfilled uv.parCondition.GetPersonValue(hh, tu[0])) { hh.SetPersonValue(hh.GetPersonValue(uv.varSpec.index, tu[0].indexInHH) * uv.GetFactor(isDBYearVarUsed ? hh.GetPersonValue(indDBYearVar, tu[0].indexInHH) : UpVar.ALLYEARS), uv.varSpec.index, tu[0].indexInHH); } } // 2nd step of uprating aggregates: build the factor of each aggregate variable as // factor_part1 * share_part1 + ... + factor_partN * share_partN = // = (part1_new / part1_old) * (part1_old / sum_parts_old) + ... + (partN_new / partN_old) * (partN_old / sum_parts_old) foreach (AggUpVar auv in aggUpVars) { if (sumParts[auv.varSpec.index] == 0) { continue; // avoid division by zero } double agg = hh.GetPersonValue(auv.varSpec.index, tu[0].indexInHH); double factor = 0; for (int i = 0; i < auv.parts.Count; ++i) { if (orParts[auv.varSpec.index][i] == 0) { continue; // avoid division by zero } double newPart = hh.GetPersonValue(auv.parts[i].index, tu[0].indexInHH); factor += (newPart / orParts[auv.varSpec.index][i]) * (orParts[auv.varSpec.index][i] / sumParts[auv.varSpec.index]); } hh.SetPersonValue(agg * factor, auv.varSpec.index, tu[0].indexInHH); } }