%22%22%22Generate%20figures%20and%20benchmark%20numbers%20for%20markowitz_paper.tex.%22%22%22%0A%0A%23%20%2F%2F%2F%20script%0A%23%20requires-python%20%3D%20%22%3E%3D3.11%22%0A%23%20dependencies%20%3D%20%5B%0A%23%20%20%20%20%20%22matplotlib%22%2C%0A%23%20%20%20%20%20%22numpy%22%2C%0A%23%20%20%20%20%20%22fast-minimum-variance%22%2C%0A%23%20%20%20%20%20%22marimo%22%0A%23%20%5D%0A%23%20%5Btool.uv.sources%5D%0A%23%20fast-minimum-variance%20%3D%20%7B%20path%20%3D%20%22..%2F..%2F..%22%2C%20editable%20%3D%20true%20%7D%0A%23%20%2F%2F%2F%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.23.5%22%0Aapp%20%3D%20marimo.App()%0A%0Awith%20app.setup%3A%0A%20%20%20%20from%20pathlib%20import%20Path%0A%0A%20%20%20%20import%20matplotlib%20as%20mpl%0A%20%20%20%20import%20matplotlib.pyplot%20as%20plt%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20from%20_common%20import%20run_timed%2C%20set_notebook_plot_style%0A%0A%20%20%20%20from%20fast_minimum_variance.problem%20import%20_Problem%20as%20Problem%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20set_notebook_plot_style(mpl)%0A%0A%20%20%20%20def%20make_constraints(N%2C%20n_sectors%2C%20cap)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Build%20(C%2C%20d)%20for%20long-only%20%2B%20equal-sized%20sector%20caps.%22%22%22%0A%20%20%20%20%20%20%20%20sector%20%3D%20np.zeros((N%2C%20n_sectors))%0A%20%20%20%20%20%20%20%20size%20%3D%20N%20%2F%2F%20n_sectors%0A%20%20%20%20%20%20%20%20for%20k%20in%20range(n_sectors)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20lo%20%3D%20k%20*%20size%0A%20%20%20%20%20%20%20%20%20%20%20%20hi%20%3D%20lo%20%2B%20size%20if%20k%20%3C%20n_sectors%20-%201%20else%20N%0A%20%20%20%20%20%20%20%20%20%20%20%20sector%5Blo%3Ahi%2C%20k%5D%20%3D%201.0%0A%20%20%20%20%20%20%20%20C%20%3D%20np.hstack(%5B-np.eye(N)%2C%20sector%5D)%0A%20%20%20%20%20%20%20%20d%20%3D%20np.concatenate(%5Bnp.zeros(N)%2C%20np.full(n_sectors%2C%20cap)%5D)%0A%20%20%20%20%20%20%20%20return%20C%2C%20d%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Section%201%3A%20Synthetic%20benchmark%20%20N%3D1000%2C%20T%3D2000%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20print(%22%3D%22%20*%2070)%0A%20%20%20%20print(%22Synthetic%20benchmark%20%20N%3D1000%2C%20T%3D2000%2C%205%20sector%20caps%20at%2025%25%22)%0A%20%20%20%20print(%22%3D%22%20*%2070)%0A%0A%20%20%20%20rng%20%3D%20np.random.default_rng(0)%0A%20%20%20%20N_bench%2C%20T_bench%20%3D%201000%2C%202000%0A%20%20%20%20X_bench%20%3D%20rng.standard_normal((T_bench%2C%20N_bench))%0A%20%20%20%20mu_bench%20%3D%20rng.standard_normal(N_bench)%0A%20%20%20%20C_bench%2C%20d_bench%20%3D%20make_constraints(N_bench%2C%205%2C%200.25)%0A%20%20%20%20alpha_bench%20%3D%20N_bench%20%2F%20(N_bench%20%2B%20T_bench)%0A%0A%20%20%20%20configs%20%3D%20%5B%0A%20%20%20%20%20%20%20%20(%22cvxpy%22%2C%20lambda%3A%20Problem(X_bench%2C%20C%3DC_bench%2C%20d%3Dd_bench%2C%20rho%3D0.5%2C%20mu%3Dmu_bench).solve_cvxpy(project%3DFalse))%2C%0A%20%20%20%20%20%20%20%20(%22kkt%22%2C%20lambda%3A%20Problem(X_bench%2C%20C%3DC_bench%2C%20d%3Dd_bench%2C%20rho%3D0.5%2C%20mu%3Dmu_bench).solve_kkt(project%3DFalse))%2C%0A%20%20%20%20%20%20%20%20(%22cg%22%2C%20lambda%3A%20Problem(X_bench%2C%20C%3DC_bench%2C%20d%3Dd_bench%2C%20rho%3D0.5%2C%20mu%3Dmu_bench).solve_cg(project%3DFalse))%2C%0A%20%20%20%20%20%20%20%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22cg_lw%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20lambda%3A%20Problem(X_bench%2C%20C%3DC_bench%2C%20d%3Dd_bench%2C%20rho%3D0.5%2C%20mu%3Dmu_bench%2C%20alpha%3Dalpha_bench).solve_cg(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20project%3DFalse%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%5D%0A%0A%20%20%20%20display%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22cvxpy%22%3A%20%22cvxpy%20(Clarabel)%22%2C%0A%20%20%20%20%20%20%20%20%22kkt%22%3A%20%22KKT%20direct%22%2C%0A%20%20%20%20%20%20%20%20%22cg%22%3A%20%22CG%20(constr.-elim.)%22%2C%0A%20%20%20%20%20%20%20%20%22cg_lw%22%3A%20%22CG%20%2B%20LW%22%2C%0A%20%20%20%20%7D%0A%0A%20%20%20%20bench_results%20%3D%20%7B%7D%0A%20%20%20%20print(f%22%7B'method'%3A%3C30%7D%20%7B'time_s'%3A%3E10%7D%20%7B'iters'%3A%3E8%7D%22)%0A%20%20%20%20print(%22-%22%20*%2052)%0A%20%20%20%20for%20key%2C%20fn%20in%20configs%3A%0A%20%20%20%20%20%20%20%20print(f%22Running%20%7Bdisplay%5Bkey%5D%7D...%22)%0A%20%20%20%20%20%20%20%20(w%2C%20iters)%2C%20t%20%3D%20run_timed(fn)%0A%20%20%20%20%20%20%20%20bench_results%5Bkey%5D%20%3D%20%7B%22time_s%22%3A%20t%2C%20%22iters%22%3A%20iters%2C%20%22w%22%3A%20w%7D%0A%20%20%20%20%20%20%20%20iters_str%20%3D%20str(iters)%20if%20iters%20is%20not%20None%20else%20%22--%22%0A%20%20%20%20%20%20%20%20print(f%22%7Bdisplay%5Bkey%5D%3A%3C30%7D%20%7Bt%3A%3E10.4f%7D%20%7Biters_str%3A%3E8%7D%22)%0A%0A%20%20%20%20ref%20%3D%20bench_results%5B%22cvxpy%22%5D%5B%22time_s%22%5D%0A%20%20%20%20print()%0A%20%20%20%20for%20key%20in%20(%22kkt%22%2C%20%22cg%22%2C%20%22cg_lw%22)%3A%0A%20%20%20%20%20%20%20%20spd%20%3D%20ref%20%2F%20bench_results%5Bkey%5D%5B%22time_s%22%5D%0A%20%20%20%20%20%20%20%20print(f%22%20%20%7Bdisplay%5Bkey%5D%7D%3A%20%7Bspd%3A.1f%7Dx%20speedup%20vs%20cvxpy%22)%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Section%202%3A%20Runtime%20vs%20N%20(constrained%20Markowitz)%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20ns%20%3D%20%5B50%2C%20100%2C%20200%2C%20300%2C%20500%2C%20750%2C%201000%5D%0A%20%20%20%20times_markowitz%20%3D%20%7Bk%3A%20%5B%5D%20for%20k%20in%20(%22kkt%22%2C%20%22cg_lw%22)%7D%0A%20%20%20%20rng2%20%3D%20np.random.default_rng(1)%0A%0A%20%20%20%20print()%0A%20%20%20%20print(%22%3D%22%20*%2070)%0A%20%20%20%20print(%22Runtime%20vs%20N%20%20(5%20sector%20caps%2C%20rho%3D0.5%2C%20LW%20shrinkage%2C%20T%3D2N)%22)%0A%20%20%20%20print(%22%3D%22%20*%2070)%0A%20%20%20%20print(f%22%7B'N'%3A%3E6%7D%20%20%7B'kkt'%3A%3E10%7D%20%20%7B'cg_lw'%3A%3E10%7D%22)%0A%20%20%20%20print(%22-%22%20*%2032)%0A%0A%20%20%20%20for%20n%20in%20ns%3A%0A%20%20%20%20%20%20%20%20T%20%3D%202%20*%20n%0A%20%20%20%20%20%20%20%20X%20%3D%20rng2.standard_normal((T%2C%20n))%0A%20%20%20%20%20%20%20%20mu%20%3D%20rng2.standard_normal(n)%0A%20%20%20%20%20%20%20%20C%2C%20d%20%3D%20make_constraints(n%2C%205%2C%200.25)%0A%20%20%20%20%20%20%20%20alpha%20%3D%20n%20%2F%20(n%20%2B%20T)%0A%20%20%20%20%20%20%20%20_%2C%20t_kkt%20%3D%20run_timed(%0A%20%20%20%20%20%20%20%20%20%20%20%20lambda%20x%3DX%2C%20cc%3DC%2C%20dd%3Dd%2C%20mm%3Dmu%3A%20Problem(x%2C%20C%3Dcc%2C%20d%3Ddd%2C%20rho%3D0.5%2C%20mu%3Dmm).solve_kkt(project%3DFalse)%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20_%2C%20t_cg%20%3D%20run_timed(%0A%20%20%20%20%20%20%20%20%20%20%20%20lambda%20x%3DX%2C%20cc%3DC%2C%20dd%3Dd%2C%20mm%3Dmu%2C%20av%3Dalpha%3A%20Problem(x%2C%20C%3Dcc%2C%20d%3Ddd%2C%20rho%3D0.5%2C%20mu%3Dmm%2C%20alpha%3Dav).solve_cg(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20project%3DFalse%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20times_markowitz%5B%22kkt%22%5D.append(t_kkt)%0A%20%20%20%20%20%20%20%20times_markowitz%5B%22cg_lw%22%5D.append(t_cg)%0A%20%20%20%20%20%20%20%20print(f%22%7Bn%3A%3E6%7D%20%20%7Bt_kkt%3A%3E10.4f%7D%20%20%7Bt_cg%3A%3E10.4f%7D%22)%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Section%203%3A%20Efficient%20frontier%20timing%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20print()%0A%20%20%20%20print(%22%3D%22%20*%2070)%0A%20%20%20%20print(%22Efficient%20frontier%20%20N%3D500%2C%20T%3D1000%2C%205%20sector%20caps%20(21%20rho%20values)%22)%0A%20%20%20%20print(%22%3D%22%20*%2070)%0A%0A%20%20%20%20N_ef%2C%20T_ef%20%3D%20500%2C%201000%0A%20%20%20%20X_ef%20%3D%20np.random.default_rng(2).standard_normal((T_ef%2C%20N_ef))%0A%20%20%20%20mu_ef%20%3D%20np.random.default_rng(3).standard_normal(N_ef)%0A%20%20%20%20C_ef%2C%20d_ef%20%3D%20make_constraints(N_ef%2C%205%2C%200.25)%0A%20%20%20%20alpha_ef%20%3D%20N_ef%20%2F%20(N_ef%20%2B%20T_ef)%0A%20%20%20%20rhos%20%3D%20np.linspace(0%2C%202%2C%2021)%0A%0A%20%20%20%20def%20frontier_kkt()%3A%0A%20%20%20%20%20%20%20%20%22%22%22Compute%20efficient%20frontier%20weights%20for%20all%20rho%20values%20using%20KKT%20direct.%22%22%22%0A%20%20%20%20%20%20%20%20return%20%5BProblem(X_ef%2C%20C%3DC_ef%2C%20d%3Dd_ef%2C%20rho%3Dr%2C%20mu%3Dmu_ef).solve_kkt(project%3DTrue)%20for%20r%20in%20rhos%5D%0A%0A%20%20%20%20def%20frontier_cg()%3A%0A%20%20%20%20%20%20%20%20%22%22%22Compute%20efficient%20frontier%20weights%20for%20all%20rho%20values%20using%20CG%20%2B%20LW.%22%22%22%0A%20%20%20%20%20%20%20%20return%20%5BProblem(X_ef%2C%20C%3DC_ef%2C%20d%3Dd_ef%2C%20rho%3Dr%2C%20mu%3Dmu_ef%2C%20alpha%3Dalpha_ef).solve_cg(project%3DTrue)%20for%20r%20in%20rhos%5D%0A%0A%20%20%20%20def%20frontier_cvxpy()%3A%0A%20%20%20%20%20%20%20%20%22%22%22Compute%20efficient%20frontier%20weights%20for%20all%20rho%20values%20using%20CVXPY%20(no%20LW).%22%22%22%0A%20%20%20%20%20%20%20%20return%20%5BProblem(X_ef%2C%20C%3DC_ef%2C%20d%3Dd_ef%2C%20rho%3Dr%2C%20mu%3Dmu_ef).solve_cvxpy(project%3DTrue)%20for%20r%20in%20rhos%5D%0A%0A%20%20%20%20def%20frontier_cvxpy_lw()%3A%0A%20%20%20%20%20%20%20%20%22%22%22Compute%20efficient%20frontier%20weights%20for%20all%20rho%20values%20using%20CVXPY%20%2B%20LW.%22%22%22%0A%20%20%20%20%20%20%20%20return%20%5BProblem(X_ef%2C%20C%3DC_ef%2C%20d%3Dd_ef%2C%20rho%3Dr%2C%20mu%3Dmu_ef%2C%20alpha%3Dalpha_ef).solve_cvxpy(project%3DTrue)%20for%20r%20in%20rhos%5D%0A%0A%20%20%20%20_%2C%20t_ef_kkt%20%3D%20run_timed(frontier_kkt)%0A%20%20%20%20_%2C%20t_ef_cg%20%3D%20run_timed(frontier_cg)%0A%20%20%20%20_%2C%20t_ef_cvxpy%20%3D%20run_timed(frontier_cvxpy)%0A%20%20%20%20_%2C%20t_ef_cvxpy_lw%20%3D%20run_timed(frontier_cvxpy_lw)%0A%0A%20%20%20%20print(f%22%20%20cvxpy%20(no%20LW)%20%20%3A%20%7Bt_ef_cvxpy%3A.3f%7D%20s%20%20(%7Bt_ef_cvxpy%20%2F%20len(rhos)%20*%201000%3A.1f%7D%20ms%2Fpoint)%22)%0A%20%20%20%20print(f%22%20%20cvxpy%20%2B%20LW%20%20%20%20%20%3A%20%7Bt_ef_cvxpy_lw%3A.3f%7D%20s%20%20(%7Bt_ef_cvxpy_lw%20%2F%20len(rhos)%20*%201000%3A.1f%7D%20ms%2Fpoint)%22)%0A%20%20%20%20print(f%22%20%20kkt%20%20%20%20%20%20%20%20%20%20%20%20%3A%20%7Bt_ef_kkt%3A.3f%7D%20s%20%20(%7Bt_ef_kkt%20%2F%20len(rhos)%20*%201000%3A.1f%7D%20ms%2Fpoint)%22)%0A%20%20%20%20print(f%22%20%20cg%20%2B%20LW%20%20%20%20%20%20%20%20%3A%20%7Bt_ef_cg%3A.3f%7D%20s%20%20(%7Bt_ef_cg%20%2F%20len(rhos)%20*%201000%3A.1f%7D%20ms%2Fpoint)%22)%0A%20%20%20%20print()%0A%20%20%20%20print(%22%20%20---%20Algorithmic%20speedup%20(same%20problem%2C%20no%20LW)%20---%22)%0A%20%20%20%20print(f%22%20%20KKT%20direct%20vs%20cvxpy%20(no%20LW)%3A%20%7Bt_ef_cvxpy%20%2F%20t_ef_kkt%3A.1f%7Dx%22)%0A%20%20%20%20print()%0A%20%20%20%20print(%22%20%20---%20Regularised%20speedup%20(both%20with%20LW%2C%20same%20problem)%20---%22)%0A%20%20%20%20print(f%22%20%20CG%2BLW%20vs%20cvxpy%2BLW%20%20%20%20%20%3A%20%7Bt_ef_cvxpy_lw%20%2F%20t_ef_cg%3A.1f%7Dx%22)%0A%20%20%20%20print()%0A%20%20%20%20print(f%22%20%20Note%3A%20applying%20LW%20to%20cvxpy%20changes%20its%20runtime%20by%20%7Babs(t_ef_cvxpy_lw%20%2F%20t_ef_cvxpy%20-%201)%20*%20100%3A.1f%7D%25%22)%0A%0A%20%20%20%20%23%20%E2%94%80%E2%94%80%20Plot%20%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%E2%94%80%0A%0A%20%20%20%20fig%2C%20(ax1%2C%20ax2)%20%3D%20plt.subplots(1%2C%202%2C%20figsize%3D(6.5%2C%202.8))%0A%0A%20%20%20%20colors%20%3D%20%7B%22kkt%22%3A%20%22%231f77b4%22%2C%20%22cg_lw%22%3A%20%22%232ca02c%22%7D%0A%20%20%20%20labels_plot%20%3D%20%7B%22kkt%22%3A%20%22KKT%20direct%22%2C%20%22cg_lw%22%3A%20%22CG%20%2B%20LW%22%7D%0A%20%20%20%20for%20key%20in%20(%22kkt%22%2C%20%22cg_lw%22)%3A%0A%20%20%20%20%20%20%20%20ax1.plot(ns%2C%20times_markowitz%5Bkey%5D%2C%20marker%3D%22o%22%2C%20markersize%3D3%2C%20label%3Dlabels_plot%5Bkey%5D%2C%20color%3Dcolors%5Bkey%5D)%0A%20%20%20%20ax1.set_xscale(%22log%22)%0A%20%20%20%20ax1.set_yscale(%22log%22)%0A%20%20%20%20ax1.set_xlabel(%22Number%20of%20assets%20%24n%24%22)%0A%20%20%20%20ax1.set_ylabel(%22Wall-clock%20time%20(s)%22)%0A%20%20%20%20ax1.set_title(r%22(a)%20Runtime%20vs.%5C%20%24n%24%20%20(5%20sector%20caps%2C%20%24%5Crho%3D0.5%24%2C%20LW)%22)%0A%20%20%20%20ax1.legend(framealpha%3D0.9)%0A%20%20%20%20ax1.grid(True%2C%20which%3D%22both%22%2C%20linestyle%3D%22%3A%22%2C%20linewidth%3D0.5%2C%20alpha%3D0.7)%0A%0A%20%20%20%20%23%20Panel%20B%3A%20efficient%20frontier%20portfolios%20(return%20vs%20variance)%2C%20using%20alpha%3Dalpha_ef%20to%0A%20%20%20%20%23%20match%20the%20Krylov%20experiments%20so%20the%20figure%20and%20timing%20comparisons%20are%20consistent.%0A%20%20%20%20ws_kkt%20%3D%20%5B%0A%20%20%20%20%20%20%20%20Problem(X_ef%2C%20C%3DC_ef%2C%20d%3Dd_ef%2C%20rho%3Dr%2C%20mu%3Dmu_ef%2C%20alpha%3Dalpha_ef).solve_kkt(project%3DTrue)%5B0%5D%0A%20%20%20%20%20%20%20%20for%20r%20in%20np.linspace(0%2C%202%2C%2051)%0A%20%20%20%20%5D%0A%20%20%20%20rets%20%3D%20%5Bmu_ef%20%40%20w%20for%20w%20in%20ws_kkt%5D%0A%20%20%20%20vols%20%3D%20%5Bfloat(np.linalg.norm(X_ef%20%40%20w))%20for%20w%20in%20ws_kkt%5D%0A%20%20%20%20%23%20Sort%20by%20risk%20so%20the%20frontier%20traces%20left-to-right.%0A%20%20%20%20_order%20%3D%20np.argsort(vols)%0A%20%20%20%20ax2.plot(np.array(vols)%5B_order%5D%2C%20np.array(rets)%5B_order%5D%2C%20marker%3D%22o%22%2C%20markersize%3D3%2C%20color%3Dcolors%5B%22kkt%22%5D)%0A%20%20%20%20ax2.set_xlabel(r%22Portfolio%20risk%20%24%5C%7CXw%5C%7C%24%22)%0A%20%20%20%20ax2.set_ylabel(r%22Expected%20return%20%24%5Cmu%5E%5Ctop%20w%24%22)%0A%20%20%20%20ax2.set_title(r%22(b)%20Efficient%20frontier%20%20(%24n%3D500%24%2C%205%20sector%20caps)%22)%0A%20%20%20%20ax2.grid(True%2C%20linestyle%3D%22%3A%22%2C%20linewidth%3D0.5%2C%20alpha%3D0.7)%0A%0A%20%20%20%20fig.tight_layout(pad%3D1.0)%0A%20%20%20%20folder%20%3D%20Path(__file__).parent%20%2F%20%22graphs%22%0A%0A%20%20%20%20fig.savefig(folder%20%2F%20%22markowitz_scaling.pdf%22%2C%20bbox_inches%3D%22tight%22)%0A%20%20%20%20fig.savefig(folder%20%2F%20%22markowitz_scaling.png%22%2C%20bbox_inches%3D%22tight%22%2C%20dpi%3D150)%0A%20%20%20%20print()%0A%20%20%20%20print(%22Saved%20graphs%2Fmarkowitz_scaling.pdf%20and%20graphs%2Fmarkowitz_scaling.png%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
87b6967e0a856e6de8fd33b6c8888ffe