bool Stage2_IPF_Data::Set_Stage_Two (IPF_Data *IPF_ptr) { int i, cell, cells, type, types; Attribute_Data *at_ptr, *new_ptr; //---- clear memory ---- Clear (); //---- add the control totals ---- cells = IPF_ptr->Num_Cells (); if (!Add_Attribute (cells)) return (false); //---- copy and expand each attribute ---- for (at_ptr = IPF_ptr->Attribute (i=1); at_ptr; at_ptr = IPF_ptr->Attribute (++i)) { if (!Add_Attribute (2 * at_ptr->Num_Types ())) return (false); } //---- set the number of cells ---- if (!Num_Cells (2 * cells)) return (false); //---- add indices and targets to the control totals ---- new_ptr = Attribute (1); if (!new_ptr->Num_Cells (Num_Cells ())) return (false); for (cell=1; cell <= cells; cell++) { new_ptr->Index (cell, cell); new_ptr->Index (cell + cells, cell); } //---- calculate cell indices for attributes ---- for (at_ptr = IPF_ptr->Attribute (i=1); at_ptr; at_ptr = IPF_ptr->Attribute (++i)) { new_ptr = Attribute (i+1); if (!new_ptr->Num_Cells (Num_Cells ())) return (false); types = at_ptr->Num_Types (); for (cell=1; cell <= cells; cell++) { type = at_ptr->Index (cell); new_ptr->Index (cell, type); new_ptr->Index (cell + cells, type + types); } } return (true); }
bool Stage2_IPF_Data::Save_Shares (PUMA_Data_Array *puma_ptr) { int cell, cells; double total, share; bool flag; //---- check the data record ---- if (Num_Cells () == 0) return (false); //---- calculate the scaling factor ---- cells = puma_ptr->Num_Cells (); total = 0.0; for (cell=1; cell <= cells; cell++) { total += Share (cell); } //---- copy the factored share to the zone record ---- flag = (total != 0.0); if (!flag) share = 0.0; for (cell=1; cell <= cells; cell++) { if (flag) { share = Share (cell) / total; } puma_ptr->Zone_Share (cell, share); } return (true); }
void IPF_Data::Zero_Share (void) { int num_cells = Num_Cells (); if (num_cells > 0) { share.assign (num_cells, 0.0); } }
bool IPF_Data::Set_Cells (void) { Attribute_Itr at_itr; int cell, index, num, base, cells, types; //---- calculate total number of cells ---- cells = 1; for (at_itr = attribute.begin (); at_itr != attribute.end (); at_itr++) { types = at_itr->Num_Types (); if (types <= 0) return (false); cells *= types; } //---- calculate cell indices ---- num = base = cells; for (at_itr = attribute.begin (); at_itr != attribute.end (); at_itr++) { if (!at_itr->Num_Cells (cells)) return (false); types = at_itr->Num_Types (); base /= types; for (cell=0; cell < cells; cell++) { index = (cell % num) / base; at_itr->Index (cell, index); } num = base; } return (Num_Cells (cells)); }
bool Stage2_IPF_Data::Copy_Stage_One (PUMA_Data_Array *puma_ptr) { int i, type, types, offset; double weight, target, share; Attribute_Type *at_ptr; Attribute_Data *new_ptr; //---- check the data record ---- if (Num_Cells () == 0) return (false); //---- copy the control total attribute ---- new_ptr = Attribute (1); types = new_ptr->Num_Types (); for (type=1; type <= types; type++) { new_ptr->Target (type, puma_ptr->PUMA_Share (type)); } weight = puma_ptr->PUMA_Total (); if (weight > 0.0) { weight = puma_ptr->Zone_Total () / weight; } //---- copy the targets for each attribute ---- for (at_ptr = puma_ptr->Attribute (i=1); at_ptr; at_ptr = puma_ptr->Attribute (++i)) { new_ptr = Attribute (i+1); types = at_ptr->Num_Types (); offset = at_ptr->Offset (); for (type=1; type <= types; type++, offset++) { share = weight * puma_ptr->Zone_Target (offset); target = puma_ptr->PUMA_Target (offset) - share; new_ptr->Target (type, share); new_ptr->Target (type + types, target); } } Zero_Share (); return (true); }
bool IPF_Data::IPF (void) { int cell; double total; bool flag; Dbl_Itr db_itr; Attribute_Itr at_itr; if (Num_Cells () == 0) return (false); //---- normalize the data ---- for (at_itr = attribute.begin (); at_itr != attribute.end (); at_itr++) { at_itr->Normalize (); } total = 0.0; for (db_itr = share.begin (); db_itr != share.end (); db_itr++) { total += *db_itr; } if (total != 1.0) { flag = (total == 0.0); if (flag) total = 1.0 / Num_Cells (); for (db_itr = share.begin (); db_itr != share.end (); db_itr++) { if (flag) { *db_itr = total; } else { *db_itr /= total; } } } //---- iterate until converence ---- for (num_iter=1; num_iter <= max_iter; num_iter++) { //---- copy the current shares ---- previous.assign (share.begin (), share.end ()); //---- process each attribute ---- for (at_itr = attribute.begin (); at_itr != attribute.end (); at_itr++) { at_itr->Zero_Total (); //---- sum the attribute totals ---- for (cell=0, db_itr = share.begin (); db_itr != share.end (); db_itr++, cell++) { at_itr->Total_Cell (cell, *db_itr); } //---- calculate the correction factors ---- if (at_itr->Factor_Total () != 0.0) { //---- apply the correction factors ---- for (cell=0, db_itr = share.begin (); db_itr != share.end (); db_itr++, cell++) { *db_itr *= at_itr->Cell_Factor (cell); } } } //---- check the convergence criteria ---- difference = 0.0; for (cell=0, db_itr = share.begin (); db_itr != share.end (); db_itr++, cell++) { difference += fabs (previous [cell] - *db_itr); } if (difference <= max_diff) return (true); } return (false); }
Sim_Veh_Data (int cells = 1) { Clear (); Num_Cells (cells); }