packages feed

hanalyze-0.1.0.0: demo/doe-optim/BayesOptDemo.hs

{-# LANGUAGE OverloadedStrings #-}
-- | Phase V: Bayesian Optimization のデモ。
--
-- 1. 単一目的 BO で sin 関数の最小値を探す
-- 2. 多目的 BO (NSGA-II 内側) で 2 目的問題の Pareto 近似を構築
module Main where

import Text.Printf (printf)
import System.Random.MWC (createSystemRandom)

import Hanalyze.Optim.BayesOpt
import Hanalyze.Model.GP (Kernel (..))

-- 単一目的: f(x) = sin(3x) + (x - 2)² / 5
-- 真の最小は x ≈ 0.96 で y ≈ -0.789
trueF :: Double -> Double
trueF x = sin (3 * x) + (x - 2) ^ (2 :: Int) / 5

-- 多目的:
--   y_1 = x²
--   y_2 = (x - 2)²
trueMO :: [Double] -> [Double]
trueMO [x] = [x * x, (x - 2) ^ (2 :: Int)]
trueMO _ = error "1D"

main :: IO ()
main = do
  putStrLn "═══════════════════════════════════════════════════════════════"
  putStrLn "  Phase V: Bayesian Optimization"
  putStrLn "═══════════════════════════════════════════════════════════════"
  putStrLn ""

  gen <- createSystemRandom

  -- ── 1. 単一目的 BO ──
  putStrLn "[1] 単一目的 BO: f(x) = sin(3x) + (x-2)²/5 on [0, 4]"
  putStrLn "    真の最小 ≈ (0.96, -0.789)"
  let cfg = defaultBayesOptConfig
              { boIterations = 15
              , boInitPoints = 4
              , boUCBBeta    = 2.0
              }
  (history, (xBest, yBest)) <- bayesOpt cfg (return . trueF) (0, 4) gen
  printf "  評価回数: %d (= 初期 %d + BO %d)\n"
         (length history) (boInitPoints cfg) (boIterations cfg)
  printf "  推定最良: x* = %.4f, y* = %.4f\n" xBest yBest
  printf "  履歴の最終 5 評価:\n"
  mapM_ (\(x, y) -> printf "    (%.4f, %.4f)\n" x y)
        (drop (length history - 5) history)
  putStrLn ""

  -- ── 2. 多目的 BO ──
  putStrLn "[2] 多目的 BO: y_1 = x², y_2 = (x-2)² on [0, 2]"
  putStrLn "    真の Pareto front: x ∈ [0, 2] で連続"
  history2 <- bayesOptMOWithNSGA 12 5 RBF (return . trueMO)
                                 [(0, 2)] gen
  printf "  評価回数: %d\n" (length history2)
  printf "  最終 5 評価:\n"
  mapM_ (\(x, y) -> printf "    x=%s, y=%s\n"
                           (show (map round3 x))
                           (show (map round3 y)))
        (drop (length history2 - 5) history2)
  putStrLn ""

  putStrLn "═══════════════════════════════════════════════════════════════"
  putStrLn "  ✓ Bayesian Optimization が動作 (単目的 BO + NSGA-II 内側)"
  putStrLn "═══════════════════════════════════════════════════════════════"

  where
    round3 :: Double -> Double
    round3 v = fromIntegral (round (v * 1000) :: Int) / 1000