Semi-successful optimization run. Unfortunately, I just got screwed by my choice of RoC rather than curvature, which means that optimization won't invert a surface

This commit is contained in:
2023-01-30 23:44:54 +01:00
parent cf300f3f88
commit 0bd2ef581c
3 changed files with 29 additions and 12 deletions

View File

@@ -15,9 +15,11 @@ import Petzval.Calculations
import Petzval.Optimization import Petzval.Optimization
import Petzval.Types import Petzval.Types
import System.Environment (getArgs) import System.Environment (getArgs)
import System.IO (hPrint, stderr)
import Linear import Linear
import Numeric.AD.Mode (Scalar, Mode) import Numeric.AD.Mode (Scalar, Mode)
import qualified Numeric.LinearAlgebra as L import qualified Numeric.LinearAlgebra as L
import qualified Data.List as DL
bk7 = SellemeierMat [ (1.03961212, 6.00069867e-3 ) bk7 = SellemeierMat [ (1.03961212, 6.00069867e-3 )
, (0.231792344, 2.00179144e-2 ) , (0.231792344, 2.00179144e-2 )
@@ -69,30 +71,33 @@ type Id a = a -> a
doOptimize steps = runWriterT $ optimizeDLS cfg vars merit system1 doOptimize steps = runWriterT $ optimizeDLS cfg vars merit system1
where merit = mkMerit [ DynMerit $ TW 50 100 $ BFL Nothing where merit = mkMerit [ DynMerit $ TW 100 100 $ BFL Nothing
, DynMerit $ TW 0 1 $ SpotSize Nothing , DynMerit $ TW 0 1 $ SpotSize Nothing
, DynMerit $ TW 0 1 $ SpotSize (Just $ TraceConditions 7 0.587618)
, DynMerit $ TW 0 1 $ SpotSize (Just $ TraceConditions 15 0.587618)
] ]
vars :: VariableSet vars :: VariableSet
vars = (ix 1 . roc) `adjoin` (ix 2 . roc) vars = (ix 1 . roc) `adjoin` (ix 2 . roc) `adjoin` (ix 2.thickness)
vars2 = undefined -- foldl1 adjoin cfg = def{maxSteps = steps,eps1=0,eps2=0}
-- [ ix 1.roc , ix 2.roc]
cfg = def{maxSteps = steps}
main :: IO () main :: IO ()
main = main =
let baked = bake 0.587618 system2 let baked = bake 0.587618 system2 :: [Element BakedIOR Double]
ep = (entrancePupil baked){position=20.4747094540} ep = (entrancePupil baked){position=20.4747094540}
fa = 20 fa = 20
in do in do
[arg] <- getArgs [arg] <- getArgs
let steps = read arg let steps = read arg
print $ L.norm_2 (L.fromList [3.0 , 4.0] :: L.Vector Double) print $ L.norm_2 (L.fromList [3.0 , 4.0] :: L.Vector Double)
doOptimize steps >>= print (result, tr) <- doOptimize steps
putStrLn $ show ep hPrint stderr result
putStrLn $ show $ rearFocalLength $ lensRTM baked putStrLn "---"
putStrLn $ show $ mconcat (seidel ep fa baked :: [Seidel Double]) mapM_ (putStrLn . DL.intercalate "," . map show) tr
-- putStrLn $ show ep
--putStrLn $ show $ rearFocalLength $ lensRTM baked
--putStrLn $ show $ mconcat (seidel ep fa baked :: [Seidel Double])
{- defaultMain [ {- defaultMain [
bgroup "merit" [ bench "system1" $ nf merit (system1 :: [Element SellemeierMat Double]) bgroup "merit" [ bench "system1" $ nf merit (system1 :: [Element SellemeierMat Double])

View File

@@ -1,5 +1,5 @@
{- LANGUAGE ImpredicativeTypes #-} {- LANGUAGE ImpredicativeTypes #-}
module Petzval.Merit (BFL(..), SpotSize(..), DynMerit(..), TW(..), Merit(..), MeritFunction, evalMerit, mkMerit) where module Petzval.Merit (BFL(..), SpotSize(..), DynMerit(..), TW(..), Merit(..), MeritFunction, TraceConditions(..), evalMerit, mkMerit) where
import Petzval.Calculations import Petzval.Calculations
import Petzval.Types import Petzval.Types
@@ -66,7 +66,7 @@ spotSize' conditions ts = rmsSize
. map fst . map fst
. map (raytrace system) . map (raytrace system)
. map (createRay Nothing ep fa) . map (createRay Nothing ep fa)
$ hexapolarPattern 10 $ hexapolarPattern 6
where where
system = systemAtWavelength (wavelength conditions) ts system = systemAtWavelength (wavelength conditions) ts
fa = auto $ fieldAngle conditions fa = auto $ fieldAngle conditions

View File

@@ -19,6 +19,7 @@ import Petzval.Optics
import Petzval.Types import Petzval.Types
import Control.Monad.Writer.Class import Control.Monad.Writer.Class
import Data.Default import Data.Default
import qualified Data.List as L
import Debug.Trace import Debug.Trace
@@ -129,6 +130,17 @@ optimizeDLS cfg vars merit system = fmap (setVars vars system . toList) $ evalSt
tell [toList y] tell [toList y]
return $ newMerit - oldMerit return $ newMerit - oldMerit
jacobian' :: ([Double] -> [Double]) -> [Double] -> [(Double, [Double])]
jacobian' fn vars = zip (fn vars) jacobian
where deltas = map (/1000) vars
jacobian = L.transpose $ varSets vars id
varSets :: [Double] -> ([Double] -> [Double]) -> [[Double]]
varSets [] _ = []
varSets (var:vars) varPfx = head : rest
where fnWithD d = fn . varPfx $ var + d : vars
delta = var / 1000
head = map (/ (2 * delta)) $ zipWith (-) (fnWithD delta) (fnWithD (-delta))
rest = varSets vars (varPfx . (var:))
jacobianAt :: Vector Double -> (Vector Double, Matrix Double) jacobianAt :: Vector Double -> (Vector Double, Matrix Double)
jacobianAt pt = let eval pt = undefined jacobianAt pt = let eval pt = undefined
(y,a) = unzip . jacobian' (\adpt -> evalMerit merit $ setVars vars (system & each.liftFp %~ auto) adpt) $ toList pt (y,a) = unzip . jacobian' (\adpt -> evalMerit merit $ setVars vars (system & each.liftFp %~ auto) adpt) $ toList pt