#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "set.h"
#include "glva.h"

void set_siwake(void){
	int ii, j;
	
	/*** 積立金の仕分け ***/
	Siwake[0] = 0.;
	for(ii=1; ii<=4; ii++){
		Jisout[ii] = 0.;
		
		for(j=13; j<=17; j++){
			Jisout[ii] += Cc[ii][j][Kyoskijun-STTY];
		}
		for(j=5; j<=8; j++){
			Jisout[ii] -= Cc[ii][j][Kyoskijun-STTY];
		}
	}
	
	if(Jisout[1]<=0.0){
		printf("一元化年度の旧厚年の支出が0です\n");
		exit(1);
	}
	
	Siwake[1] = Cc[1][20][Kyoskijun-1-STTY] + Jyutaku[Kyoskijun-1-STTY];
	for(ii=2; ii<=4; ii++){
		Siwake[ii] = Jisout[ii] * Siwake[1] / Jisout[1];
		Siwake[0] += Siwake[ii];
	}
}


void shus_shushi(int ks, int ke){
	/* ks年度以降ke年度までの収支(Cc)を作成 */
	int k;
	int ii;
	
	
	for(k=ks; k<=ke; k++){
		if(k==Kyoskijun) set_siwake();
		for(ii=1; ii<=4; ii++){
			Cc[ii][4][k-STTY]  =  Cc[ii][5][k-STTY] + Cc[ii][6][k-STTY]
			                    + Cc[ii][7][k-STTY] + Cc[ii][8][k-STTY];
			Cc[ii][12][k-STTY] =  Cc[ii][13][k-STTY] + Cc[ii][14][k-STTY] + Cc[ii][15][k-STTY];
			Cc[ii][11][k-STTY] =  Cc[ii][12][k-STTY] + Cc[ii][16][k-STTY]
			                    + Cc[ii][17][k-STTY] + Cc[ii][18][k-STTY];
			/* 妻積みを除く運用収入*/
			if(ii==1 || k>Kyoskijun){
				Cc[ii][3][k-STTY]  =  Cc[ii][20][k-1-STTY] * Ri[k-ECSTY]
					                + (  Cc[ii][1][k-STTY]  + Cc[ii][4][k-STTY] + Cc[ii][9][k-STTY]
					                + Cc[ii][10][k-STTY] - Cc[ii][11][k-STTY]         ) * Ri2[k-ECSTY];
			}
			if(k==Kyoskijun){  /* 一元化年度の共済の運用収入（妻積分配を除く） 仕分け分＋収支分 */
			    Dc[ii][4] = Dc[ii][5] + Dc[ii][6] + Dc[ii][7] + Dc[ii][8];
			    Dc[ii][12]= Dc[ii][13]+ Dc[ii][14]+ Dc[ii][15];
			    Dc[ii][11]= Dc[ii][12] + Dc[ii][16] + Dc[ii][17];
				Dc[ii][3]  = Siwake[ii] * Ri2[k-ECSTY]
				            +(Dc[ii][1] + Dc[ii][4] + Dc[ii][10] - Dc[ii][11])
				                    * (pow(1.0+Ri[k-ECSTY],3.0/12.0) - 1.0);
			}
			if(k>=Kyoskijun){
				/* 妻積みの分配(収入項目として別掲扱い) */
				if(k>Kyoskijun){
					Cc[ii][3][k-STTY]     += Cc[ii][30][k-STTY] * Ri2[k-ECSTY];
				} else if(k==Kyoskijun){
					if(ii==1){
						Cc[ii][3][k-STTY] += Cc[ii][30][k-STTY] * (pow(1.0+Ri[k-ECSTY],2.0/12.0) - 1.0);
					}
					Dc[ii][3]  += Cc[ii][30][k-STTY] * (pow(1.0+Ri[k-ECSTY],2.0/12.0) - 1.0);
				}
			}
			if(ii==1 || k>Kyoskijun){
				Cc[ii][0][k-STTY]  =  Cc[ii][1][k-STTY] + Cc[ii][3][k-STTY]  + Cc[ii][4][k-STTY]
				                    + Cc[ii][9][k-STTY] + Cc[ii][10][k-STTY];
			    Cc[ii][0][k-STTY] += Cc[ii][30][k-STTY];
				Cc[ii][19][k-STTY] =  Cc[ii][0][k-STTY] - Cc[ii][11][k-STTY];
			}
			if (k==Kyoskijun){
				Dc[ii][0]  = Dc[ii][1] + Dc[ii][3] + Dc[ii][4] + Dc[ii][9] +Dc[ii][10]
				            +Cc[ii][30][k-STTY];
				Dc[ii][19] = Dc[ii][0] - Dc[ii][11];
			}
			if(k > Kijun){
				Cc[ii][20][k-STTY] = Cc[ii][20][k-1-STTY] + Cc[ii][19][k-STTY];
				if(ii==1 && k==Kyoskijun) Dc[ii][20] = Cc[ii][20][k-STTY];
				if(ii>1){
					if(k==Kyoskijun) {
						Dc[ii][20]         = Siwake[ii] + Dc[ii][19];
						Cc[ii][20][k-STTY] = Dc[ii][20];
					} else if(k<Kyoskijun) {
						Cc[ii][20][k-STTY] = 0.;
					}
				}
			} else {
				Cc[ii][0][k-STTY] = Cc[ii][3][k-STTY] = Cc[ii][19][k-STTY] = 0.;
			}
			
			/*** 一元化試算時 ***/
			if(ii==1){  /* ii=1 現厚年をセット */
				Cc[0][0][k-STTY]  = Cc[ii][0][k-STTY];
				Cc[0][3][k-STTY]  = Cc[ii][3][k-STTY];
				Cc[0][4][k-STTY]  = Cc[ii][4][k-STTY];
				Cc[0][11][k-STTY] = Cc[ii][11][k-STTY];
				Cc[0][12][k-STTY] = Cc[ii][12][k-STTY];
				Cc[0][19][k-STTY] = Cc[ii][19][k-STTY];
				Cc[0][20][k-STTY] = Cc[ii][20][k-STTY];
			} else {  /* ii>1 共済の足しこみ */
				if(k>Kyoskijun){
					Cc[0][0][k-STTY]  += Cc[ii][0][k-STTY];
					Cc[0][3][k-STTY]  += Cc[ii][3][k-STTY];
					Cc[0][4][k-STTY]  += Cc[ii][4][k-STTY];
					Cc[0][11][k-STTY] += Cc[ii][11][k-STTY];
					Cc[0][12][k-STTY] += Cc[ii][12][k-STTY];
					Cc[0][19][k-STTY] += Cc[ii][19][k-STTY];
					Cc[0][20][k-STTY] += Cc[ii][20][k-STTY];
				} else if(k==Kyoskijun){
					Cc[0][0][k-STTY] += Dc[ii][0];
					Cc[0][3][k-STTY] += Dc[ii][3];
					Cc[0][4][k-STTY] += Dc[ii][4];
					Cc[0][11][k-STTY]+= Dc[ii][11];
					Cc[0][12][k-STTY]+= Dc[ii][12];
					Cc[0][19][k-STTY]+= Dc[ii][19];
					Cc[0][20][k-STTY]+= Dc[ii][20];
				}
			}
		}
	}
}



void shus_ave(int ks, int ke, int calhh, int calhp){
	/* 年度間値を計算ks〜ke,比例を計算する場合:1,基礎・定額を計算する場合:1 */
	int k, jj, x, dx;
	int ii;
	
	int etoc[14] = {13,14,15,6,7,8,16,5,16,5,16,5,16,5};
	double riv, bpre, bend;
	
	/****************************************************************/
	/*** ESCUTTH等は、XA(64)-1歳以降数字が入っている              ***/
	/*** E3dxbは、65歳は０、66歳以降に数字が入っていることが前提  ***/
	/****************************************************************/
	
	for(ii=0; ii<=4; ii++){
		/* 収支の再初期化 */
		for(jj=0; jj<=7; jj++){
			if(calhh<=0 && (jj==0 || jj==3)) continue;
			if(calhp<=0 && (jj==1 || jj==2 || jj>=4)) continue;
			for(k=ks; k<=ke; k++){
				Cc[ii][etoc[jj]][k-STTY] = 0.;
			}
			if(ks<=Kyoskijun && ke>=Kyoskijun) Dc[ii][etoc[jj]] = 0.;
		}
		
		if(ii==0) continue;
		
		for(jj=0; jj<=9; jj++){
			if(calhh<=0 && (jj==0 || jj==3)) continue;
			if(calhp<=0 && (jj==1 || jj==2 || jj>=4)) continue;
			for(k=ks; k<=ke; k++){
				for(x=66; x<=XB; x++){
					if(jj==2 || jj==8 || jj==9) dx=67;
					else                        dx=x;
					
					if(jj==0 || jj==3){
						/***  比例系の計算   ***/
						riv = Krb[k-ECSTY][dx-ECXA] * (Escutrrh[k-ECSTY][dx-ECXA]/Escutrrh[k-1-ECSTY][dx-1-ECXA]);
						bpre = E3dxb[ii][jj][k-1-STTY][x-1] * Escutrrh[k-1-ECSTY][dx-1-ECXA];
						bend = E3dxb[ii][jj][k-STTY][x] * Escutrrh[k-ECSTY][dx-ECXA];
					} else if (jj==1 || jj==2 || jj==4 || jj==5){
						/***  定額系の計算 ***/
						riv = Kra[k-ECSTY][dx-ECXA] * (Escutrrt[k-ECSTY][dx-ECXA]/Escutrrt[k-1-ECSTY][dx-1-ECXA]);
						bpre = E3dxb[ii][jj][k-1-STTY][x-1] * Escutrrt[k-1-ECSTY][dx-1-ECXA];
						bend = E3dxb[ii][jj][k-STTY][x] * Escutrrt[k-ECSTY][dx-ECXA];
					} else if(jj==6 || jj==7 || jj==8 || jj==9) {
						/***  基礎年金拠出金の計算 ***/
						riv = Kra[k-ECSTY][dx-ECXA] * (Escutrrt[k-ECSTY][dx-ECXA]/Escutrrt[k-1-ECSTY][dx-1-ECXA]);
						bpre = E3dxb[ii][jj][k-STTY][x-1] * Escutrrt[k-1-ECSTY][dx-1-ECXA];
						bend = E3dxb[ii][jj+4][k-STTY][x] * Escutrrt[k-ECSTY][dx-ECXA];
					}
					
					if(k==13) riv += 0.010;
					
					Cc[ii][etoc[jj]][k-STTY] += (bpre * 2. + bpre * riv * 6. + bend * 4.) / 12.;
					if(k==Kyoskijun){
						if(jj==6 || jj==7 || jj==8 || jj==9){
							Dc[ii][etoc[jj]] += (bpre * 2. + bpre * riv * 6. + bend * 4.) / 24.;
						} else {
							Dc[ii][etoc[jj]] += (bpre * riv * 2. + bend * 4.) / 12.;
						}
					}
				}
				if(jj<=2){
					Cc[ii][etoc[jj]][k-STTY] *= 1.002;
					if(k==Kyoskijun) Dc[ii][etoc[jj]] *= 1.002;
				}
			}
		}
		/** 一元化時の全厚年の足しこみ **/
		for(jj=0; jj<=7; jj++){
			if(calhh<=0 && (jj==0 || jj==3)) continue;
			if(calhp<=0 && (jj==1 || jj==2 || jj>=4)) continue;
			for(k=ks; k<=ke; k++){
				if(k>Kyoskijun || ii==1){
					Cc[0][etoc[jj]][k-STTY] += Cc[ii][etoc[jj]][k-STTY];
				} else if(k==Kyoskijun){
					Cc[0][etoc[jj]][k-STTY] += Dc[ii][etoc[jj]];
				}
			}
		}
	}
}



void shus_calc0(void){	/* カット前収支の作成（Cc初期化） */
	shus_ave(Ks+1, Ke, 1, 1);	/* 給付費の計算（比例、基礎定額を計算） */
	shus_shushi(Ks+1, Ke);	/* 収支計算 */
}



int shus_calc8(void){	/* 国年先決め100年均衡 */
	int k, x, dx;
	int flg_end, kk, kn, kend, n;
	double rh[ECEDY-ECSTY+1][116-ECXA];
	double rrh_max[116-ECXA], rrh_min[116-ECXA], dtemp, dtemp2;
	double dcutr;
	double r, r0, r1, f, f0, f1;
	
	/* カット率等のセット */
	kend = atoi(Cutrfile3) + 100;
	kn = kend + 1;
	
	for(k=5; k<=Ke; k++){
		/* カット率のセット（kou） */
		for(x=ECXA; x<=XB; x++){
			if(x<68){
				dx = 67;
				dcutr = MAX(0.0, Scutrk1[k-ECSTY]);
			} else {
				dx = x;
				dcutr = MAX(0.0, Scutrk2[k-ECSTY]);
			}
			if(Flg_Dmakuro != 1 || k < Dmakuro_Yr){
				rh[k-ECSTY][x-ECXA] = 1.0 + MAX(0.0, MIN(dcutr, Krb[k-ECSTY][dx-ECXA]-1.0));
				if(k==14 && x<=76) rh[k-ECSTY][x-ECXA]=nround(0.978/0.9761,3);
			} else {
				rh[k-ECSTY][x-ECXA] = 1.0 + MAX(0.0, dcutr);
			}
		}
		
		/* 厚年のカット率設定 */
		if(k<=Kijun){
			Escutrrh[k-ECSTY][XA-1-ECXA] = Escutrrh[k-1-ECSTY][XA-1-ECXA] / rh[k-ECSTY][XA-1-ECXA];
			for(x=XA; x<=XB; x++){
				Escutrrh[k-ECSTY][x-ECXA] = Escutrrh[k-1-ECSTY][x-1-ECXA] / rh[k-ECSTY][x-ECXA];
			}
		} else {
			Escutrrh[k-ECSTY][XA-1-ECXA] = Escutrrh[k-1-ECSTY][XA-1-ECXA];
			for(x=XA; x<=XB; x++){
				Escutrrh[k-ECSTY][x-ECXA] = Escutrrh[k-1-ECSTY][x-1-ECXA];
			}
		}
		/* 国年のカット率設定 */
		for(x=XA-1; x<=XB; x++){
			Escutrrt[k-ECSTY][x-ECXA] = Scutrrki[k-ECSTY][x-ECXA];
		}
	}
	
	
	/* 初回収支計算 */
	shus_ave(Kijun, Ke, 1, 1);	/* 給付費の計算（比例、基礎定額を計算） */
	shus_shushi(Kijun+1, Ke);	/* 収支計算 */
	f0 = 0.0;
	f1 = Cc[0][20][kend-1-STTY]-Cc[0][11][kend-STTY] * Ca;
	
	/* スライド調整終了年度を求める */
	flg_end = 1;
	for(k=Kijun+1; k<Ke && flg_end>0; k++){
		Escutrrh[k-ECSTY][XA-1-ECXA] = Escutrrh[k-1-ECSTY][XA-1-ECXA] / rh[k-ECSTY][XA-1-ECXA];
		for(x=XA; x<=XB; x++){
			Escutrrh[k-ECSTY][x-ECXA] = Escutrrh[k-1-ECSTY][x-1-ECXA] / rh[k-ECSTY][x-ECXA];
		}
		for(kk=k+1; kk<=Ke; kk++){
			Escutrrh[kk-ECSTY][XA-1-ECXA] = Escutrrh[kk-1-ECSTY][XA-1-ECXA];
			for(x=XA; x<=XB; x++){
				Escutrrh[kk-ECSTY][x-ECXA] = Escutrrh[kk-1-ECSTY][x-1-ECXA];
			}
		}
		shus_ave(k, Ke, 1, 0);	/* 給付費の計算（比例、基礎定額を計算） */
		shus_shushi(k, Ke);	/* 収支計算 */
		f0 = f1;
		f1 = Cc[0][20][kend-1-STTY]-Cc[0][11][kend-STTY] * Ca;
		if(f1 >= 0.0 && k>=14){
			kn = k;
			flg_end = 0;
		}
	}
	if(kn > kend || flg_end>0){
		printf("最終年度まで調整しても均衡できませんでした\n");
		return(1);
	}
	
	/* 最終年度のスライドの調整処理 */
	for(x=XA-1; x<=XB; x++){
		rrh_max[x-ECXA] = Escutrrh[kn-ECSTY][x-ECXA];
		rrh_min[x-ECXA] = Escutrrh[kn-1-ECSTY][MAX(x-1, XA-1)-ECXA];
	}
	if(kn>14) flg_end = 1;
	else      flg_end = 0;
	r0 = 0.0; r1 = 1.0;
	for(n=0; n<62 && flg_end>0; n++){
		if(n<14){
			r = r1 - f1 * (r1-r0)/(f1-f0);
		} else {
			r = (r1 + r0) / 2.0;
		}
		for(x=XA-1; x<=XB; x++){
			Escutrrh[kn-ECSTY][x-ECXA] = rrh_min[x-ECXA] * (1.0-r) + rrh_max[x-ECXA] * r;
		}
		for(kk=kn+1; kk<=Ke; kk++){
			Escutrrh[kk-ECSTY][XA-1-ECXA] = Escutrrh[kk-1-ECSTY][XA-1-ECXA];
			for(x=XA; x<=XB; x++){
				Escutrrh[kk-ECSTY][x-ECXA] = Escutrrh[kk-1-ECSTY][x-1-ECXA];
			}
		}
		shus_ave(kn, Ke, 1, 0);	/* 給付費の計算（比例、基礎定額を計算） */
		shus_shushi(kn, Ke);	/* 収支計算 */
		f = Cc[0][20][kend-1-STTY] - Cc[0][11][kend-STTY] * Ca;
		if(fabs(Cc[0][20][kend-1-STTY]/Cc[0][11][kend-STTY] - Ca) < 0.5E-13){
			flg_end = 0;
		} else if (f * f0 > 0.0) {
			r0 = r; f0 = f;
		} else {
			r1 = r; f1 = f;
		}
	}
	if (flg_end>0){
		printf("収束しましせんでした\n");
		return(1);
	}
	
	
	print_number();
	printf(" 最終代替率\n");
	dtemp = (Mhirei[Ke-STTY][0]*Escutrrh[Ke-ECSTY][67-ECXA] + Mkiso[Ke-STTY]*Escutrrt[Ke-ECSTY][67-ECXA])
	       / Kw[Ke-STTY][0] *100.;
	dtemp2= (Mhirei[Ke-STTY][1]*Escutrrh[Ke-ECSTY][67-ECXA] + Mkiso[Ke-STTY]*Escutrrt[Ke-ECSTY][67-ECXA])
	       / Kw[Ke-STTY][1] *100.;
	printf("  一元化モデル：%.1f\n", dtemp, dtemp2);
	dtemp = Mhirei[Ke-STTY][0]*Escutrrh[Ke-ECSTY][67-ECXA] / Kw[Ke-STTY][0] *100.;
	dtemp2= Mkiso[Ke-STTY]    *Escutrrt[Ke-ECSTY][67-ECXA] / Kw[Ke-STTY][0] *100.;
	printf("      うち比例：%.1f , うち基礎：%.1f\n", dtemp, dtemp2);
	
	printf(" 最終カット率  厚年： %.3f,      国年： %.3f\n",
	       1.0-Escutrrh[kend-ECSTY][67-ECXA], 1.0-Escutrrt[kend-ECSTY][67-ECXA]);
	return(0);	
}




void shus_calc9(void){	/* カットファイル指定の収支作成 */
	int k, x;
	
	print_number();
	/* カット率のセット */
	for(k=5; k<=Ke; k++){
		for(x=XA-1; x<=XB; x++){
			Escutrrh[k-ECSTY][x-ECXA] = Scutrrh[k-ECSTY][x-ECXA];
			Escutrrt[k-ECSTY][x-ECXA] = Scutrrt[k-ECSTY][x-ECXA];
		}
	}
	/* 給付費等の計算 */
	shus_ave(Kijun, Ke, 1, 1);	/* 給付費の計算（比例、基礎定額を計算） */
	shus_shushi(Kijun+1, Ke);	/* 収支計算 */
}


void shus_smodel(void){
	int k, i;
	int mdlk = 14;
	double hsr_r = 1.0E-2;
	double kasho = 0.814;
	double nin[5] = {25280.892, 22437.424, 2793.468, 50.000, 12533.586};
	
	Mkiso[mdlk-STTY] = 128200. * 0.997;
	
	W[mdlk-STTY][0] = 427698.;
	W[mdlk-STTY][1] = 412119.;
	W[mdlk-STTY][2] = 558425.;
	W[mdlk-STTY][3] = 115000.;
	W[mdlk-STTY][4] = 268502.;
	
	for(i=0; i<5; i++){
		Kw[mdlk-STTY][i]= round(W[mdlk-STTY][i] * kasho);
		Mhirei[mdlk-STTY][i]
		  = round(W[mdlk-STTY][i] * 5.481E-3 * 0.962 * 40.) / 0.998;
	}
	
	for(k=mdlk+1; k<=Ke; k++){
		if(k>31) hsr_r = 0.;
		W[k-STTY][1] = (1.0+H[k-1-ECSTY])
		              *( W[k-1-STTY][1]
		                - nin[4]/(nin[1]+nin[4]) * hsr_r * (W[k-1-STTY][1]-W[k-1-STTY][4]) );
		W[k-STTY][4] = (1.0+H[k-1-ECSTY])
		              *( W[k-1-STTY][4]
		                + nin[1]/(nin[1]+nin[4]) * hsr_r * (W[k-1-STTY][1]-W[k-1-STTY][4]) );
		W[k-STTY][2] = (1.0+H[k-1-ECSTY]) * W[k-1-STTY][2];
		W[k-STTY][3] = (1.0+H[k-1-ECSTY]) * W[k-1-STTY][3];
		W[k-STTY][0] = 0.;
		for(i=1; i<=3; i++){
			W[k-STTY][0] += W[k-STTY][i] * nin[i];
		}
		W[k-STTY][0] /= nin[0];
		
		for(i=0; i<5; i++){
			Kw[k-STTY][i] = Kw[k-1-STTY][i] * W[k-STTY][i] / W[k-1-STTY][i]
			                 * (0.91-Prema[1][k-1-STTY]/2.) / (0.91-Prema[1][k-2-STTY]/2.);
			Mhirei[k-STTY][i] = Mhirei[k-1-STTY][i] * Kw[k-STTY][i] / Kw[k-1-STTY][i];
		}
		Mkiso[k-STTY] = Mkiso[k-1-STTY] * (1.0+H[k-1-ECSTY])
		               * (0.91-Prema[1][k-1-STTY]/2.) / (0.91-Prema[1][k-2-STTY]/2.); 
	}
	Mkiso[mdlk-STTY] = nround(Mkiso[mdlk-STTY] / 0.997, -2);
}
