Virtual U.org
Get Personal Training on VU Today
    
Top shadow
 
 register/help
User Name:

Password:

Oenrolsl.cpp Source File
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

Oenrolsl.cpp

Go to the documentation of this file.
00001 //Filename              : OEnrolsl.cpp
00002 //Description   : EnrollRes Class Definition
00003 //                                              - handle enrollment of sl-2 to sl-5 (NONTRADTION to DISTANCE_LEARN)
00004 //                                              - calc aid and talent for all levels
00005 //Owner                 : Fred
00006 
00007 #include <stdio.h>                                // for DEBUG
00008 
00009 // ES library header file
00010 #include <ALL.H>
00011 #include <OGAMESET.H>
00012 #include <OMATH.H>                                // average_float, gammaCDF
00013 #include <OSTR.h>                                 // strcmp
00014 #include <OLINALG.H>                              // for this calc_enroll_offers
00015 
00016 // CU header file
00017 #include <GAMEDEF.H>                              // enum { NONMINORITY_MALE, NONMINORITY_FEMALE, MINORITY_MALE, MINORITY_FEMALE };
00018 #include <OPSCHOOL.H>
00019 #include <OPEERSCH.H>
00020 #include <OSCHLRES.H>
00021 #include <ODEPTRES.H>
00022 #include <ODEPT.H>
00023 #include <OLIBTECH.H>                             //## chea 270999
00024 
00025 #include "OEnroll.h"
00026 
00027 //----------- Define helper static functions ------//
00028 
00029 static inline bool is_minority_group(char group) {
00030     return group == MINORITY_MALE || group == MINORITY_FEMALE;
00031 }
00032 
00033 static float multipler_special_ug(char sl, char subSeg) {
00034     err_when(sl==UG_TRADITION);
00035     float avg = is_minority_group(subSeg) ? 0.8f : 0.9f;
00036 
00037     return is_nontradition_ug_group(sl) ? math.get_random_snd(avg, PSCH_SD(0.05f)) : 1.0f;
00038 }
00039 
00040 //----------- Begin of function EnrollRes::load_db_student_pref2 ------//
00044 void EnrollRes::init_data_sls(char sl) {
00045     char arrSL = sl-1;                              // for array access
00046     err_when(UG_NONTRADITION != 1);
00047 
00048     //----------------------------------------------------//
00049     //-- initialization: td3.4 section 3.2                                      ---//
00050     //----------------------------------------------------//
00051 
00052     //---- STEP 1. calc enroll_data_sls[][].student_pref -----//
00053 
00054     const float STU_PREF_SCALE = 4.0f;
00055 
00056     float prefVarsArray[PREFERECNE_COUNT2];         // column Q
00057     int i, j;
00058 
00059     PeerSchool* player = school_res.player_peer_school;
00060     memcpy(prefVarsArray, player->pref_vars_array, sizeof(prefVarsArray));
00061 
00062     for (i=0; i<PREFERECNE_COUNT2; i++) {
00063         if ( i < PREFERECNE_COUNT2 - 4 )
00064             prefVarsArray[i] = math.safe_divide(prefVarsArray[i], PeerSchool::pref_vars_average_array[i]);
00065         else {
00066             if (  ( sl == UG_NONTRADITION && fraction_sl2_offered_aid > 0 )
00067                   || ( sl == DISTANCE_LEARN && fraction_sl5_offered_aid > 0 )
00068                 )
00069                 prefVarsArray[i] = math.safe_divide(player->pref_vars_array_last[i], PeerSchool::pref_vars_average_array_last[i]);
00070             else
00071                 prefVarsArray[i] = 0;
00072         }
00073     }
00074 
00075     err_when(PUBLIC != 1);
00076 
00077     char  isPublic = player_school.control == PUBLIC;
00078     float finalRatio[MINORITY_GROUP_COUNT];         // stuPrefs
00079     float tmpRatio;
00080     float tmp, sign;
00081 
00082     for (j=0; j<MINORITY_GROUP_COUNT; j++) {
00083         finalRatio[j] = 1;
00084 
00085         for (i=0; i<PREFERECNE_COUNT2; i++) {
00086             sign = (pref_special_case(i))? -1.0f: 1.0f;
00087 
00088             // 1
00089             tmp = enroll_res.preference_array2_sls[arrSL][isPublic][j][i];
00090 
00091             if ( tmp <= 0.0 || prefVarsArray[i] == 0)
00092                 tmpRatio = 1.0f;
00093             else
00094                 tmpRatio = math.safe_pow(prefVarsArray[i], sign * tmp);
00095 
00096 #if(GAME_VERSION>=200)
00097             if ( arrSL == 3 ) {                         // special setting for Distance Learning
00098                 //                              tmpRatio = math.safe_pow(               Kenneth
00099             }
00100 #endif
00101 
00102             // 2
00103             finalRatio[j] *= tmpRatio;
00104             err_when( finalRatio[j] < 0 );
00105         }
00106 
00107         if ( !(1+ (float) exp(-s_slope*(finalRatio[j]-1))) )
00108             finalRatio[j] = 1;
00109         else
00110             finalRatio[j] = s_lower_bound+(s_upper_bound-s_lower_bound)/(1+ (float) exp(-s_slope*(finalRatio[j]-1)));
00111 
00112         //---- save the student preference for future use ----//
00113 
00114         if ( j == MINORITY ) {
00115             enroll_data_sls[arrSL][MINORITY_MALE].student_pref = finalRatio[j];
00116             enroll_data_sls[arrSL][MINORITY_FEMALE].student_pref = finalRatio[j];
00117         }
00118         else {
00119             enroll_data_sls[arrSL][NONMINORITY_MALE].student_pref = finalRatio[j];
00120             enroll_data_sls[arrSL][NONMINORITY_FEMALE].student_pref = finalRatio[j];
00121         }
00122 
00123         err_when( finalRatio[j] < 0 );
00124     }
00125 
00126     //-------//
00127     EnrollDataSL1* ed;
00128     EnrollData* edSL;
00129     char subSeg, seg;
00130     // 0.3 -> 30%
00131     float studentGenderPct[STUDENT_SUBSEGMENT_COUNT]; {
00132 
00133         err_when(GENDER_ETHNIC_TYPE_COUNT != STUDENT_SUBSEGMENT_COUNT);
00134         float femalePercent = student_female_percent[sl] / 100.0f;
00135         float minorityPercent = student_minority_percent[sl] / 100.0f;
00136 
00137         //askbill inital gender percent affect future enrollment?  BUG? = 0 when sl=5
00138         studentGenderPct[MINORITY_FEMALE] = femalePercent*minorityPercent;
00139         studentGenderPct[NONMINORITY_FEMALE] = femalePercent*(1.0f - minorityPercent);
00140         studentGenderPct[MINORITY_MALE] = (1.0f - femalePercent)*minorityPercent;
00141         studentGenderPct[NONMINORITY_MALE] = (1.0f - femalePercent)*(1.0f - minorityPercent);
00142 
00143         for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ )
00144             enroll_data_sls[arrSL][subSeg].fraction_matrics = studentGenderPct[subSeg];
00145     }
00146 
00147     //---- STEP 2 -----//
00148 
00149     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00150         float appTmp, totalFraction;
00151         Talent acaTmp;
00152 
00153         for ( seg=0, appTmp=0, acaTmp.average=0, totalFraction=0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
00154             ed = &enroll_data_sl1[subSeg][seg];
00155 
00156             appTmp += ed->apps_ratio * ed->fraction_matrics;
00157             acaTmp.average += talent_array[subSeg][seg][ACADEMIC].average * ed->fraction_matrics;
00158 
00159             totalFraction += ed->fraction_matrics;
00160         }
00161 
00162         //--------- calc enroll_data_sls[][].apps_ratio, applications and conversion_rate ---------//
00163         edSL = &enroll_data_sls[arrSL][subSeg];
00164 
00165         edSL->apps_ratio
00166             //BUGHERE
00167             = math.safe_pow(edSL->student_pref, 1.0f) * appTmp / totalFraction
00168             //                  = math.safe_pow(edSL->student_pref, STU_PREF_SCALE) * appTmp / totalFraction
00169             ;                                           //+ math.get_random_snd(0, 0.1f * enroll_data_sls[sl][subSeg].apps_ratio);//askbill
00170 
00171         edSL->applications
00172             = enroll_data_sls[arrSL][subSeg].base_apps
00173             = int(edSL->apps_ratio
00174                   // 0.5: rounding
00175                   * studentGenderPct[subSeg] * target_student_intake[sl] + 0.5);
00176 
00177         edSL->conversion_rate
00178             = enroll_data_sls[arrSL][subSeg].base_conversion_rate
00179             //990514
00180             = m.fmin(1.0f, math.safe_divide(1.0f, edSL->apps_ratio));
00181 
00182         if ( sl == DOCTOR )                           // 990514
00183             edSL->conversion_rate =
00184                 //min & max bug chea (max)
00185                 m.fmin(m.fmax(0.0f,math.get_random_snd(0.5f,PSCH_SD(0.07f))), math.safe_divide(1.0f, edSL->apps_ratio));
00186 
00187         err_if ( sl == DOCTOR && edSL->conversion_rate > 0.99 )
00188             err_here();                                 //int x=0;
00189 
00190         //--------- calc enroll_data_sls[][].academic ratings: average and variance ---------//
00191 
00192         // means[sL,geg],variances[sL,geg]
00193 
00194         edSL->academic.average
00195             = ( multipler_special_ug(sl, subSeg) )
00196             * math.safe_pow(edSL->student_pref, STU_PREF_SCALE) * acaTmp.average / totalFraction
00197             ;                                           //+ math.get_random_snd(0, 0.1f * enroll_data_sls[sl][subSeg].academic.average);//askbill
00198 
00199         if ( sl == UG_NONTRADITION ) {
00200             for ( seg=0, acaTmp.variance = 0; seg<STUDENT_SEGMENT_COUNT; seg++ ) {
00201                 ed = &enroll_data_sl1[subSeg][seg];
00202 
00203                 acaTmp.variance +=
00204                     ( talent_array[subSeg][seg][ACADEMIC].variance
00205                       + (float) math.safe_pow( multipler_special_ug(sl, subSeg) * talent_array[subSeg][seg][ACADEMIC].average
00206                                                - enroll_data_sls[arrSL][subSeg].academic.average, 2)
00207                         ) * ed->fraction_matrics;
00208             }
00209 
00210             edSL->academic.variance
00211                 = acaTmp.variance / totalFraction;
00212         }
00213         else
00214             edSL->academic.variance = enroll_data_sls[UG_NONTRADITION-1][subSeg].academic.variance;
00215 
00216         err_when(edSL->applications < 0);
00217         err_when(edSL->academic.average < 0);
00218     }
00219 
00220     //-----------------//
00221 
00222     calc_enroll_aid_sls(sl);
00223 }
00224 
00225 //------------- End of function EnrollRes::load_db_student_pref2 ------//
00226 
00227 //----------- Begin of function EnrollRes::calc_enroll_aid_sls ------//
00231 void EnrollRes::calc_enroll_aid_sls(char sl) {
00232     float fractionOfferedMeritAid = 0;
00233 
00234     if (  ( sl == UG_NONTRADITION ) ) {
00235         adjust_fraction_merit_aid(fraction_sl2_offered_aid);
00236 
00237         if ( fraction_sl2_offered_aid <= 0 ) {
00238             merit_lower[sl] = 1;
00239             merit_upper[sl] = 0;
00240             return;
00241         }
00242 
00243         fractionOfferedMeritAid = fraction_sl2_offered_aid;
00244     }
00245     else if ( sl == DISTANCE_LEARN ) {
00246         adjust_fraction_merit_aid(fraction_sl5_offered_aid);
00247 
00248         if ( fraction_sl5_offered_aid <= 0 ) {
00249             merit_lower[sl] = 1;
00250             merit_upper[sl] = 0;
00251             return;
00252         }
00253 
00254         fractionOfferedMeritAid = fraction_sl5_offered_aid;
00255     }
00256     else if ( sl == DOCTOR ) {
00257         merit_lower[sl] = max_aid;
00258         merit_upper[sl] = max_aid;
00259         return;
00260     }
00261     else {
00262         merit_lower[sl] = 1;
00263         merit_upper[sl] = 0;
00264         return;
00265     }
00266 
00267     //-------------------//
00268     //---- Merit Aid ----//
00269     //-------------------//
00270 
00271     /*
00272 
00273       mL2 = With[{tmp = frNonTradStudentsOfferedAid*
00274       Plus@@((conversionRate[sL2,#]*frPriorMatrics[sL2,#])&/@gegs)},
00275       FindMinimum[(meritFrObj[sL2,x]-tmp)^2,{x,5}][[2,1,2]]];
00276     */
00277 
00278     float adjustRatio=0;
00279     char subSeg, arrSL = sl-1;
00280 
00281     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00282         adjustRatio
00283             += enroll_data_sls[arrSL][subSeg].conversion_rate
00284             * enroll_data_sls[arrSL][subSeg].fraction_matrics;
00285     }
00286 
00287     float x = 5, deviate, lastDeviate;
00288     float inc = x / 100.f;
00289     float offset = fractionOfferedMeritAid * adjustRatio;
00290 
00291     if ( calc_merit_aid_sls(sl, x+inc, offset)
00292          > calc_merit_aid_sls(sl, x-inc, offset) )
00293         inc *= -1;
00294 
00295     deviate = calc_merit_aid_sls(sl, x, offset);
00296 
00297     do {
00298         x += inc;
00299         lastDeviate = deviate;
00300         deviate = calc_merit_aid_sls(sl, x, offset);
00301     }
00302     while ( deviate < lastDeviate && deviate > 0 );
00303 
00304     merit_lower[sl] = x;
00305 
00306     /*
00307       mH2 =  With[{tmp = frMeritTop*
00308       Plus@@((conversionRate[sL2,#]*frPriorMatrics[sL2,#])&/@gegs)},
00309       FindMinimum[(meritFrObj[sL2,x]-tmp)^2,{x,6}][[2,1,2]]],
00310     */
00311 
00312     x = 6;
00313     inc = x / 100.f;
00314     offset = fraction_merit_top * adjustRatio;
00315 
00316     if ( calc_merit_aid_sls(sl, x+inc, offset)
00317          > calc_merit_aid_sls(sl, x-inc, offset) )
00318         inc *= -1;
00319 
00320     deviate = calc_merit_aid_sls(sl, x, offset);
00321 
00322     do {
00323         x += inc;
00324         lastDeviate = deviate;
00325         deviate = calc_merit_aid_sls(sl, x, offset);
00326     }
00327     while ( deviate < lastDeviate && deviate > 0 );
00328 
00329     merit_upper[sl] = x;
00330 }
00331 
00332 //------------- End of function EnrollRes::calc_enroll_aid_sls ------//
00333 
00334 //----------- Begin of function EnrollRes::calc_merit_aid_sls --------//
00339 float EnrollRes::calc_merit_aid_sls(char sl, float aid, float base) {
00340     float deviate = 0, cdfTmp;
00341 
00342     float aidMinMultiplier;
00343     char  subSeg, arrSL=sl-1;
00344     EnrollData  *ed;
00345 
00346     // meritFrObj[sL2,mL_] := Plus@@Flatten[meritFrObj[sL2,mL,#]&/@gegs];
00347     // meritFrObj[sL2,mL_,geg_] := (1-cdf[acadR,sL2,geg,mL])*frPriorMatrics[sL2,geg];
00348 
00349     // cdf[acadR,sL_,geg_,x_] := gammaCDF[minMultF[aid,geg]*means[sL,geg],variances[sL,geg],x];
00350 
00351     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00352         if ( !is_minority_group(subSeg) )
00353             aidMinMultiplier = 1.0f;
00354         else
00355             aidMinMultiplier = aidMinMultipliers[minority_aid_special];
00356 
00357         ed = &enroll_data_sls[arrSL][subSeg];
00358 
00359         cdfTmp = math.get_random_gamma_CDF( aidMinMultiplier * ed->academic.average,
00360                                             PSCH_SD(ed->academic.variance), aid );
00361 
00362         deviate += (1-cdfTmp) * ed->fraction_matrics;
00363     }
00364 
00365     return math.safe_pow(deviate - base, 2);
00366 }
00367 
00368 //----------- End of function EnrollRes::calc_merit_aid_sls --------//
00369 
00370 //----------- Begin of function EnrollRes::enroll_main_sls ------//
00374 void EnrollRes::enroll_main_sls(char sl) {
00375     //----------------------------------------------------//
00376     //-- main procedures: td3.4 section 3.3                             ---//
00377     //----------------------------------------------------//
00378 
00379     /*
00380       getApps[sL_] := ((applications[sL,#] =
00381       Round[(1-matsLatency[sL])*stuPrefs[sL,#]*baseApps[sL,#] +
00382       matsLatency[sL]*applications[sL,#]])&/@gegs;
00383 
00384       totalApps[sL] = Plus@@Flatten[applications[sL,#]&/@gegs]);
00385     */
00386 
00387     char  subSeg, arrSL=sl-1;
00388     EnrollData  *edSL;
00389     float idealMatrics = 0;
00390     float totalMatrics = 0;
00391 
00392     total_applications[sl] = 0;
00393 
00394     //## chea 110899 avoid 0 Matrics
00395 
00396     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00397         if(enroll_data_sls[arrSL][subSeg].conversion_rate <= 0 && target_student_intake[sl] > 0) {
00398             enroll_data_sls[arrSL][subSeg].conversion_rate=1;
00399         }
00400     }
00401 
00402     /*  // this is the org. idea
00403         for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ )
00404         {
00405         edSL = &enroll_data_sls[arrSL][subSeg];
00406 
00407         edSL->applications = int( 0.5 + math.get_random_snd(chance_avg, chance_sd, true)
00408         + (1-apps_latency[sl]) * app_multiplier[arrSL] * edSL->student_pref * edSL->base_apps
00409         + apps_latency[sl] * edSL->applications );
00410 
00411         total_applications[sl] += edSL->applications;
00412         idealMatrics += edSL->applications * edSL->conversion_rate;
00413 
00414         err_when(edSL->applications < 0);
00415         }
00416     */
00417 
00418     //## chea 270999 my idea
00419     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00420         edSL = &enroll_data_sls[arrSL][subSeg];
00421 
00422         if(sl ==2 || sl ==3 || sl ==1) {
00423             edSL->applications = int( 0.5 + math.get_random_snd(chance_avg, PSCH_SD(chance_sd), true)
00424                                       + (1-apps_latency[sl]) * app_multiplier[arrSL] * edSL->student_pref * edSL->base_apps
00425                                       + apps_latency[sl] * edSL->applications );
00426         }
00427         /*
00428           else if(sl==4 && player_school.school_type == 1 && info.prerun_year == 1)
00429           {
00430           edSL->applications = 10;
00431           }
00432         */
00433         else {
00434             edSL->applications = int( 0.5 + math.get_random_snd(chance_avg, PSCH_SD(chance_sd), true)
00435                                       + (1-apps_latency[sl]) * app_multiplier[arrSL] * edSL->student_pref * edSL->base_apps
00436                                       + apps_latency[sl] * edSL->applications);
00437         }
00438 
00439         total_applications[sl] += edSL->applications;
00440         totalMatrics += edSL->applications * edSL->conversion_rate;
00441 
00442         err_when(edSL->applications < 0);
00443     }
00444 
00445     idealMatrics = math.safe_divide( (float) target_student_intake[sl], totalMatrics);
00446 
00447 #if(GAME_VERSION>=200)
00448     // no need bound by 1
00449 #else
00450     //990514
00451     if ( sl == DOCTOR )
00452         idealMatrics = min(1.0f,idealMatrics);        //min & max bug chea
00453 #endif
00454 
00455     //----------------------------------------------------//
00456 
00457     //if ( sl == DOCTOR && idealMatrics <= 0 )
00458     //  err_here();     //int x=0;
00459 
00460     total_matrics[sl] = 0;
00461 
00462     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00463         edSL = &enroll_data_sls[arrSL][subSeg];
00464 
00465         edSL->matrics = int ( 0.5 + min(
00466             //min & max bug chea
00467             (float)(edSL->applications), idealMatrics * edSL->conversion_rate * edSL->applications ));
00468 
00469         total_matrics[sl] += edSL->matrics;
00470 
00471         err_when(edSL->matrics < 0);
00472         //if ( sl == DOCTOR && edSL->conversion_rate > 0.99 )
00473         //      err_here();     //int x=0;
00474     }
00475 
00476 #if(GAME_VERSION>=200)
00477     // Item 8d i)
00478     if ( sl == 4 ) {
00479         int input1;
00480         switch ( distance_learner_acceptance ) {
00481         case 0: input1 = 0;             break;
00482         case 1: input1 = 8 * edSL->applications;  break;
00483         case 2: input1 = 16 * edSL->applications;
00484         }
00485 
00486         total_matrics[sl] = player_school.latency_func( 0.7f, total_matrics[sl], input1 );
00487     }
00488 #endif
00489 
00490     //  if ( idealMatrics >= total_matrics[sl] )
00491     //          err_here();     //int x=0;
00492 
00493     //----------------------------------------------------//
00494 
00495     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00496         edSL = &enroll_data_sls[arrSL][subSeg];
00497 
00498         edSL->fraction_matrics = math.safe_divide((edSL->matrics), total_matrics[sl]);
00499         edSL->conversion_rate = math.safe_divide((edSL->matrics), edSL->applications);
00500 
00501         err_when(edSL->conversion_rate < 0 || edSL->conversion_rate > 1);
00502     }
00503 
00504     //----------------------------------------------------//
00505     // calc getMinAcadRating
00506 
00507     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00508         edSL = &enroll_data_sls[arrSL][subSeg];
00509 
00510         float x = 5, deviate, lastDeviate;
00511         float inc = x / 100.f;
00512         float offset = 1 - edSL->conversion_rate;
00513 
00514         if ( calc_academic_rating(sl, subSeg, x+inc, offset)
00515              > calc_academic_rating(sl, subSeg, x-inc, offset) )
00516             inc *= -1;
00517 
00518         deviate = calc_academic_rating(sl, subSeg, x, offset);
00519 
00520         do {
00521             x += inc;
00522             lastDeviate = deviate;
00523             deviate = calc_academic_rating(sl, subSeg, x, offset);
00524         }
00525         while ( deviate < lastDeviate && deviate > 0 );
00526 
00527         min_academic_rating[arrSL] = min(x, 10.0f);   //min & max bug chea
00528     }
00529 
00530     /*
00531       getMinAcadRating[sL_,geg_,y_] := FindMinimum[(cdf[acadR,sL,geg,x]-(1-y))^2,{x,5}][[2,1,2]];
00532 
00533       getAcadRatings[sL_] := (
00534       (minAcadRating[sL,#] = Min[getMinAcadRating[sL,#,conversionRate[sL,#]],10])&/@gegs;
00535       minAcadRating[sL]   = Min[minAcadRating[sL,#]&/@gegs];    )
00536     */
00537 }
00538 
00539 //------------- End of function EnrollRes::enroll_main_sls ------//
00540 
00541 //----------- Begin of function EnrollRes::calc_academic_rating --------//
00545 float EnrollRes::calc_academic_rating(char sl, char subSeg, float academicRating, float base) {
00546     float deviate = 0, cdfTmp, aidMinMultiplier;
00547 
00548     char  arrSL=sl-1;
00549     EnrollData  *ed;
00550 
00551     // cdf[acadR,sL_,geg_,x_] := gammaCDF[minMultF[aid,geg]*means[sL,geg],variances[sL,geg],x];
00552 
00553     if ( !is_minority_group(subSeg) )
00554         aidMinMultiplier = 1.0f;
00555     else
00556         aidMinMultiplier = aidMinMultipliers[minority_aid_special];
00557 
00558     ed = &enroll_data_sls[arrSL][subSeg];
00559 
00560     cdfTmp = math.get_random_gamma_CDF( aidMinMultiplier * ed->academic.average,
00561                                         PSCH_SD(ed->academic.variance), academicRating);
00562 
00563     deviate = cdfTmp;
00564 
00565     return math.safe_pow(deviate - base, 2);
00566 }
00567 
00568 //----------- End of function EnrollRes::calc_academic_rating --------//
00569 
00570 //----------- Begin of function EnrollRes::calc_post_enroll_sls --------//
00574 void EnrollRes::calc_post_enroll_sls(char sl) {
00575     //-------------------------//
00576     //           generate student               //
00577     //-------------------------//
00578 
00579     EnrollData *edSL;
00580     char  subSeg, seg=-1;
00581     int newStudentCount, i, arrSL=sl-1;
00582 
00583     // temp vars storing new sim properties
00584     float talentArr[TALENT_VAR_COUNT];
00585     int aid=0;
00586 
00587     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00588         edSL = &enroll_data_sls[arrSL][subSeg];
00589         newStudentCount = edSL->matrics;
00590 
00591         for (i=0; i<newStudentCount; i++) {
00592             char subSegStu = subSeg;
00593 
00594             if ( info.year_passed == 1 && player_school.scenario_id == SCN_STUDENT_DIVERSITY ) {
00595                 if ( is_minority_group(subSeg) && math.get_random_float () > 0.571f ) {
00596                     if (subSegStu == MINORITY_MALE )
00597                         subSegStu = NONMINORITY_MALE;
00598                     else
00599                         subSegStu = NONMINORITY_FEMALE;
00600                 }
00601             }
00602 
00603             //------- calc 3 talent values and aid
00604 
00605             calc_a_talent(talentArr, sl, subSegStu);
00606 
00607             // 990408
00608             /*if ( sl == DOCTOR && talentArr[ACADEMIC] < min_academic_rating[arrSL] )
00609               {
00610               // if acadRating < minAcadRating, then discard this applicant
00611               edSL->matrics--;
00612               continue;
00613               }*/
00614 
00615             //-------  Generate student; see also PlayerSchool::generate_student()
00616             //
00617 
00618             if ( is_nontradition_ug_group(sl) ) {
00619                 // all year 1 ug students start without major
00620                 department_res.general_dept.student_array.add( sl, 1, subSegStu, seg, 0, int(aid), talentArr );
00621             }
00622             else {
00623                 int major = player_school.get_random_major(sl);
00624                 department_array[major]->student_array.add( sl, 1, subSegStu, seg, major, int(aid), talentArr );
00625             }
00626 
00627             //-------  update vars for calc average later
00628 
00629             talent_average[sl][ACADEMIC] += int( 10 * talentArr[ACADEMIC]);
00630         }
00631     }
00632 
00633     //----------------------------------------------------//
00634 
00635     // recalc matrics since some are discarded above
00636 
00637     //----------------------------------------------------//
00638 
00639 #if(GAME_VERSION>=200)
00640     if ( sl != 4 ) {                                // Not distance learning
00641 #endif
00642         total_matrics[sl] = 0;
00643 
00644         for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00645             edSL = &enroll_data_sls[arrSL][subSeg];
00646 
00647             total_matrics[sl] += edSL->matrics;
00648 
00649             err_when(edSL->matrics < 0);
00650         }
00651 #if(GAME_VERSION>=200)
00652     }
00653 #endif
00654     //----------------------------------------------------//
00655 
00656     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00657         edSL = &enroll_data_sls[arrSL][subSeg];
00658 
00659         edSL->fraction_matrics = math.safe_divide((edSL->matrics), total_matrics[sl]);
00660         edSL->conversion_rate = math.safe_divide((edSL->matrics), edSL->applications);
00661 
00662         err_when(edSL->conversion_rate < 0 || edSL->conversion_rate > 1);
00663     }
00664 
00665     //----------------------------------------------------//
00666     //990408
00667 
00668     int subOffer = 0;
00669 
00670     for ( subSeg=0; subSeg<STUDENT_SUBSEGMENT_COUNT; subSeg++ ) {
00671         edSL = &enroll_data_sls[arrSL][subSeg];
00672 
00673         subOffer += int( edSL->matrics + (edSL->applications - edSL->matrics ) *
00674                          m.fmin(1.0f, m.fmax(0.0f,math.get_random_snd(edSL->conversion_rate,
00675                                                                       PSCH_SD(edSL->conversion_rate * 0.1f)))) ); //min & max bug chea
00676     }
00677 
00678     //total_offers[sl] = int(total_matrics[sl] * 1.4f);
00679     total_offers[sl] = subOffer;
00680 }
00681 
00682 //----------- End of function EnrollRes::calc_post_enroll_sls --------//
00683 
00684 //----------- Begin of function EnrollRes::calc_an_aid --------//
00689 float EnrollRes::calc_an_aid(Student *stuPtr) {
00690     char sl = stuPtr->student_level;
00691     char subSeg = stuPtr->gender_ethnic_group;
00692     char seg = stuPtr->student_segment;
00693 
00694     //------- calc need and merit aid
00695     EnrollDataSL1 *ed;
00696     Talent *talentPtr;
00697     float utility, needAid, meritAid, income;
00698     float aid;
00699 
00700     if ( sl == 0 ) {
00701         err_when(seg < 0 || seg >= STUDENT_SEGMENT_COUNT);
00702 
00703         ed = &enroll_data_sl1[subSeg][seg];
00704         talentPtr = &(talent_array[subSeg][seg][ACADEMIC]);
00705 
00706         // ## chea 100899 use small variance to change aid
00707         //              income = math.get_random_snd(talentPtr[INCOME].average, float(sqrt(talentPtr[INCOME].variance)), true );
00708         //              utility = math.get_random_snd(ed->util, float(sqrt(ed->util_variance)), true );
00709 
00710         income = math.get_random_snd(talentPtr[INCOME].average, PSCH_SD(float(sqrt(talentPtr[INCOME].variance))/4.0f), true );
00711         utility = math.get_random_snd(ed->util, PSCH_SD(float(sqrt(ed->util_variance))/4.0f), true );
00712 
00713         // adjust utility
00714 
00715         if ( seg == STUDENT_SEGMENT_ATHLETE ) {
00716             switch (athlete_offers_special) {
00717             case SET_HIGH:
00718                 utility = max(utility,10.0f);           // min & max bug chea
00719                 break;
00720             case SET_MID:
00721                 utility = ( 10 + utility ) / 2;
00722                 break;
00723             default:
00724                 break;
00725             }
00726         }
00727 
00728         //---- calc need and merit aid ---------//
00729 
00730         if ( income < need_lower )
00731             needAid = fraction_need_covered * max_aid;
00732         else if ( income < need_upper )
00733             needAid = fraction_need_covered * max_aid * (need_upper-income) / (need_upper - need_lower);
00734         else
00735             needAid = 0;
00736 
00737         if ( fraction_sl1_offered_merit_aid <= 0 )
00738             merit_upper[sl] = 10;
00739 
00740         if ( utility > merit_upper[sl] )
00741             meritAid = max_aid - needAid;
00742         else if ( utility > merit_lower[sl] )
00743             // min & max bug chea
00744             meritAid = max( max_aid * float(utility - merit_lower[sl]) / (merit_upper[sl] - merit_lower[sl]) - needAid, 0.0f );
00745         else
00746             meritAid = 0;
00747 
00748         //meritAid = 0;         //990408
00749         err_when(need_upper == need_lower);
00750         err_when(merit_upper[sl] == merit_lower[sl]);
00751 
00752         //------------------ calc final aid
00753 
00754         err_when(needAid + meritAid > max_aid + 0.15);
00755 
00756         aid = ((needAid + meritAid));
00757 
00758         if ( seg == STUDENT_SEGMENT_ATHLETE ) {
00759             switch (athlete_aid_special) {
00760             case SET_HIGH:
00761                 aid = ( max_aid);
00762                 break;
00763             case SET_MID:
00764                 aid = ( (max_aid+aid) / 2.0f);
00765                 break;
00766             default:
00767                 break;
00768             }
00769         }
00770     }
00771 
00772     //-------- sl2-5 -----------//
00773 
00774     else {
00775         //--- mertiAid only
00776         // utility = academic rating in sl2-5
00777         utility = float(stuPtr->talent_academic) / 10;
00778 
00779         if ( sl == DOCTOR )
00780             meritAid = max_aid;
00781         else if ( merit_upper[sl] < merit_lower[sl] )
00782             meritAid = 0;
00783         else if ( utility > merit_upper[sl] )
00784             meritAid = max_aid;                         //0223
00785         else if ( utility > merit_lower[sl] )
00786             // min & max bug chea
00787             meritAid = max( max_aid * float(utility - merit_lower[sl]) / (merit_upper[sl] - merit_lower[sl]), 0.0f );
00788         else
00789             meritAid = 0;
00790 
00791         aid = (meritAid);
00792     }
00793 
00794     err_when(aid > (max_aid + 0.10));
00795     total_aid += aid;
00796 
00797     return aid;
00798 }
00799 
00800 //----------- End of function EnrollRes::calc_an_aid --------//
00801 
00802 //----------- Begin of function EnrollRes::calc_a_talent --------//
00805 void EnrollRes::calc_a_talent(float talentArr[TALENT_VAR_COUNT], char sl, char subSeg, char seg) {
00806     err_when(subSeg < 0 || subSeg >= STUDENT_SUBSEGMENT_COUNT);
00807 
00808     if ( sl == UG_TRADITION ) {
00809         err_when(seg < 0 || seg >= STUDENT_SEGMENT_COUNT);
00810 
00811         Talent *talentPtr;
00812         talentPtr = &(talent_array[subSeg][seg][ACADEMIC]);
00813 
00814         for (char t=0; t<TALENT_VAR_COUNT; t++)
00815             talentArr[t] = math.get_random_snd(talentPtr[t].average, PSCH_SD(float(sqrt(talentPtr[t].variance))), true );
00816     }
00817     else {
00818         char arrSL = sl-1;
00819         EnrollData *edSL;
00820 
00821         edSL = &enroll_data_sls[arrSL][subSeg];       // enroll_data_sls[MAX_STUDENT_LEVEL_NO_SL1][STUDENT_SUBSEGMENT_COUNT];
00822 
00823         if ( sl == DOCTOR )
00824             // min & max bug chea
00825             talentArr[ACADEMIC] = m.fmin(100.0f, math.get_random_snd(math.single_response_func(0.7f, 1.3f, 100, 50, edSL->academic.average), PSCH_SD(float(sqrt(edSL->academic.variance))), true ));
00826         else
00827             talentArr[ACADEMIC] = math.get_random_snd(edSL->academic.average, PSCH_SD(float(sqrt(edSL->academic.variance))), true );
00828         talentArr[EXTRA_CURRI] = talentArr[ATHLETIC] = 0;
00829 
00830     }
00831 
00832     //## chea 161299 testing only
00833     //  talentArr[0]=talentArr[1]=talentArr[2] = 3.3f;
00834 
00835 }
00836 
00837 //----------- End of function EnrollRes::calc_a_talent --------//
00838 
00839 //------------- End of function EnrollRes::calc_talent_student_db --------//
00840 //
00841 // calc talent of students in db: returning student
00842 //
00843 void EnrollRes::calc_talent_student_db() {
00844     StudentArray* stuArr;
00845     Student *stuPtr;
00846     float talentArr[TALENT_VAR_COUNT];
00847     int stuCount=0, i, j;
00848 
00849     err_when( department_array.size() == 0 );
00850     for ( i=department_array.size(); i>=0; i-- ) {
00851         if (i) {
00852             if ( department_array.is_deleted(i) )
00853                 continue;
00854 
00855             stuArr = &(department_array[i]->student_array);
00856         }
00857         else
00858             stuArr = &(department_res.general_dept.student_array);
00859 
00860         // loop student
00861         for (j=stuArr->size(); j>0; j--) {
00862             if ( stuArr->is_deleted(j) )
00863                 continue;
00864 
00865             stuPtr = stuArr->operator[](j);
00866 
00867             char studentLevel = stuPtr->student_level;
00868             char stuSeg = stuPtr->student_segment;
00869             char genderEthnicGroup = stuPtr->gender_ethnic_group;
00870 
00871             if ( studentLevel == UG_TRADITION ) {
00872                 //-------- assume: enroll_res.init() (dbf init) called --------//
00873                 calc_a_talent(talentArr, studentLevel, genderEthnicGroup, stuSeg);
00874             }
00875             else {
00876                 //-------- assume: value will be assigned after enroll_res.init_data() called
00877                 calc_a_talent(talentArr, studentLevel, genderEthnicGroup);
00878             }
00879             //## 071299 chea 1.12.1
00880             // min & max bug chea
00881             stuPtr->talent_academic       = (char) max(0.0f,min(100.0f, talentArr[ACADEMIC] * 10));
00882             //                  stuPtr->talent_academic                         = 33; //##200100 cHEA
00883 
00884             // min & max bug chea
00885             stuPtr->talent_extracurricular  = (char) max(0.0f,min(100.0f, talentArr[EXTRA_CURRI] * 10));
00886             // min & max bug chea
00887             stuPtr->talent_athletics      = (char) max(0.0f,min(100.0f, talentArr[ATHLETIC] * 10));
00888 
00889             //                  stuPtr->talent_academic                         = (char) max(0.0f,min(100.0f, talentArr[ACADEMIC])); // min & max bug chea
00890             //                  stuPtr->talent_extracurricular  = (char) max(0.0f,min(100.0f, talentArr[EXTRA_CURRI])); // min & max bug chea
00891             //                  stuPtr->talent_athletics                        = (char) max(0.0f,min(100.0f, talentArr[ATHLETIC])); // min & max bug chea
00892 
00893             stuCount++;
00894         }
00895     }
00896 
00897     err_when(stuCount != total_student_count);
00898 }
00899 
00900 //------------- End of function EnrollRes::calc_talent_student_db--------//
00901 
00902 // ##### Begin Marco #### //
00903 #if(GAME_VERSION>=200)
00904 // ----------- Begin of function EnrollRes::save_initial_data --------//
00905 void EnrollRes::save_initial_data() {
00906     for (int i = 0; i < MAX_STUDENT_LEVEL; i++) {
00907         initial_offers_rate[i] = offers_rate[i];
00908         initial_cur_yield_rate[i] = cur_yield_rate[i];
00909     }
00910 
00911     initial_matrics_top_athletes = matrics_top_athletes;
00912 }
00913 
00914 // ----------- End of function EnrollRes::save_initial_data --------//
00915 #endif
00916 // ##### End Marco #### //

Generated on Fri Aug 23 01:37:28 2002 for VirtualU by doxygen1.2.17