@@ -13477,12 +13477,161 @@
1347713477 " randorient(k, p, xi, seed=1)"
1347813478 ]
1347913479 },
13480+ {
13481+ "cell_type" : " markdown" ,
13482+ "metadata" : {},
13483+ "source" : [
13484+ " # Morris-Mitchell\n "
13485+ ]
13486+ },
1348013487 {
1348113488 "cell_type" : " code" ,
13482- "execution_count" : null ,
13489+ "execution_count" : 2 ,
1348313490 "metadata" : {},
13484- "outputs" : [],
13485- "source" : []
13491+ "outputs" : [
13492+ {
13493+ "name" : " stdout" ,
13494+ "output_type" : " stream" ,
13495+ "text" : [
13496+ " Design | Original mmphi (Extensive) | New mmphi_intensive (Intensive)\n " ,
13497+ " ----------------------------------------------------------------------------\n " ,
13498+ " LHS (N=20) | 41.3303 | 2.9984 \n " ,
13499+ " Random (N=20) | 68.7818 | 4.9900 \n " ,
13500+ " LHS (N=50) | 136.7957 | 3.9084 \n " ,
13501+ " Random (N=50) | 179.4802 | 5.1280 \n "
13502+ ]
13503+ }
13504+ ],
13505+ "source" : [
13506+ " # --- Experimental Setup ---\n " ,
13507+ " from spotpython.utils.sampling import jd, mmphi, mmphi_intensive\n " ,
13508+ " from scipy.stats import qmc\n " ,
13509+ " import numpy as np\n " ,
13510+ " \n " ,
13511+ " N_DIM = 2\n " ,
13512+ " Q_EXP = 2.0\n " ,
13513+ " P_NORM = 2.0 # Euclidean distance\n " ,
13514+ " \n " ,
13515+ " # We will compare two high-quality LHS designs of different sizes\n " ,
13516+ " # with two lower-quality random designs of the same sizes.\n " ,
13517+ " lhs_design_20 = qmc.LatinHypercube(d=N_DIM, seed=1).random(n=20)\n " ,
13518+ " random_design_20 = np.random.default_rng(1).random(size=(20, N_DIM))\n " ,
13519+ " \n " ,
13520+ " lhs_design_50 = qmc.LatinHypercube(d=N_DIM, seed=2).random(n=50)\n " ,
13521+ " random_design_50 = np.random.default_rng(2).random(size=(50, N_DIM))\n " ,
13522+ " \n " ,
13523+ " designs_to_test = {\n " ,
13524+ " \" LHS (N=20)\" : lhs_design_20,\n " ,
13525+ " \" Random (N=20)\" : random_design_20,\n " ,
13526+ " \" LHS (N=50)\" : lhs_design_50,\n " ,
13527+ " \" Random (N=50)\" : random_design_50,\n " ,
13528+ " }\n " ,
13529+ " \n " ,
13530+ " results = []\n " ,
13531+ " for label, design in designs_to_test.items():\n " ,
13532+ " raw_score = mmphi(design, q=Q_EXP, p=P_NORM)\n " ,
13533+ " intensive_score = mmphi_intensive(design, q=Q_EXP, p=P_NORM)\n " ,
13534+ " results.append({\n " ,
13535+ " \" Design\" : label,\n " ,
13536+ " \" Original mmphi (Extensive)\" : f\" {raw_score:.4f}\" ,\n " ,
13537+ " \" New mmphi_intensive (Intensive)\" : f\" {intensive_score:.4f}\" ,\n " ,
13538+ " })\n " ,
13539+ " \n " ,
13540+ " # --- Print Results Table ---\n " ,
13541+ " headers = list(results[0].keys())\n " ,
13542+ " widths = {h: max(len(h), max(len(row[h]) for row in results)) for h in headers}\n " ,
13543+ " \n " ,
13544+ " header_line = \" | \" .join(h.ljust(widths[h]) for h in headers)\n " ,
13545+ " print(header_line)\n " ,
13546+ " print(\" -\" * len(header_line))\n " ,
13547+ " \n " ,
13548+ " for row in results:\n " ,
13549+ " row_line = \" | \" .join(row[h].ljust(widths[h]) for h in headers)\n " ,
13550+ " print(row_line)"
13551+ ]
13552+ },
13553+ {
13554+ "cell_type" : " code" ,
13555+ "execution_count" : 7 ,
13556+ "metadata" : {},
13557+ "outputs" : [
13558+ {
13559+ "name" : " stdout" ,
13560+ "output_type" : " stream" ,
13561+ "text" : [
13562+ " Running comparative analysis...\n " ,
13563+ " \n " ,
13564+ " Design | Original mmphi | Intensive mmphi\n " ,
13565+ " -------------------------------------------------------------\n " ,
13566+ " Good Design (LHS, N=20) | 497.4601 | 4.7058 \n " ,
13567+ " Poor Design (Random, N=20) | 587.2249 | 5.5550 \n " ,
13568+ " Good Design (LHS, N=50) | 515.4561 | 4.8436 \n " ,
13569+ " Poor Design (Random, N=50) | 589.4369 | 5.5388 \n " ,
13570+ " \n " ,
13571+ " --- Interpretation ---\n " ,
13572+ " Notice how 'Original mmphi' scores are not comparable between N=20 and N=50 designs.\n " ,
13573+ " The 'Intensive mmphi' scores, however, are comparable. The two 'Good' LHS designs have\n " ,
13574+ " similar low scores, which are clearly better (lower) than the scores for the 'Poor' random designs.\n "
13575+ ]
13576+ }
13577+ ],
13578+ "source" : [
13579+ " # --- Helper function for design generation ---\n " ,
13580+ " def generate_design(n_points: int, n_dim: int, seed: int, design_type: str) -> np.ndarray:\n " ,
13581+ " if design_type == 'lhs':\n " ,
13582+ " sampler = qmc.LatinHypercube(d=n_dim, seed=seed)\n " ,
13583+ " return sampler.random(n=n_points)\n " ,
13584+ " elif design_type == 'random':\n " ,
13585+ " rng = np.random.default_rng(seed)\n " ,
13586+ " return rng.random(size=(n_points, n_dim))\n " ,
13587+ " else:\n " ,
13588+ " raise ValueError(\" Unknown design type\" )\n " ,
13589+ " \n " ,
13590+ " # --- Analysis Parameters ---\n " ,
13591+ " N_DIM = 2\n " ,
13592+ " Q_EXP = 2.0\n " ,
13593+ " P_NORM = 2.0 # Euclidean distance\n " ,
13594+ " \n " ,
13595+ " designs_to_compare = {\n " ,
13596+ " \" Good Design (LHS, N=20)\" : generate_design(150, N_DIM, 42, 'lhs'),\n " ,
13597+ " \" Poor Design (Random, N=20)\" : generate_design(150, N_DIM, 42, 'random'),\n " ,
13598+ " \" Good Design (LHS, N=50)\" : generate_design(151, N_DIM, 42, 'lhs'),\n " ,
13599+ " \" Poor Design (Random, N=50)\" : generate_design(151, N_DIM, 42, 'random')\n " ,
13600+ " }\n " ,
13601+ " \n " ,
13602+ " results = []\n " ,
13603+ " \n " ,
13604+ " print(\" Running comparative analysis...\\ n\" )\n " ,
13605+ " for label, design in designs_to_compare.items():\n " ,
13606+ " # Calculate original (extensive) metric\n " ,
13607+ " original_score = mmphi(design, q=Q_EXP, p=P_NORM)\n " ,
13608+ " \n " ,
13609+ " # Calculate new (intensive) metric\n " ,
13610+ " intensive_score = mmphi_intensive(design, q=Q_EXP, p=P_NORM)\n " ,
13611+ " \n " ,
13612+ " results.append({\n " ,
13613+ " 'Design': label,\n " ,
13614+ " 'Original mmphi': f\" {original_score:.4f}\" ,\n " ,
13615+ " 'Intensive mmphi': f\" {intensive_score:.4f}\"\n " ,
13616+ " })\n " ,
13617+ " \n " ,
13618+ " # --- Print Results Table ---\n " ,
13619+ " headers = list(results[0].keys())\n " ,
13620+ " widths = {h: max(len(h), max(len(row[h]) for row in results)) for h in headers}\n " ,
13621+ " \n " ,
13622+ " header_line = \" | \" .join(h.ljust(widths[h]) for h in headers)\n " ,
13623+ " print(header_line)\n " ,
13624+ " print(\" -\" * len(header_line))\n " ,
13625+ " \n " ,
13626+ " for row in results:\n " ,
13627+ " row_line = \" | \" .join(row[h].ljust(widths[h]) for h in headers)\n " ,
13628+ " print(row_line)\n " ,
13629+ " \n " ,
13630+ " print(\"\\ n--- Interpretation ---\" )\n " ,
13631+ " print(\" Notice how 'Original mmphi' scores are not comparable between N=20 and N=50 designs.\" )\n " ,
13632+ " print(\" The 'Intensive mmphi' scores, however, are comparable. The two 'Good' LHS designs have\" )\n " ,
13633+ " print(\" similar low scores, which are clearly better (lower) than the scores for the 'Poor' random designs.\" )\n "
13634+ ]
1348613635 },
1348713636 {
1348813637 "cell_type" : " code" ,
0 commit comments