joel-woodfield commited on
Commit
cda1627
·
1 Parent(s): 552eeb7

Do not reset trajectory when plot has relayout

Browse files
backend/src/optimization_manager.py CHANGED
@@ -35,6 +35,12 @@ class OptimizationManager:
35
  if new_settings == self.settings:
36
  return None
37
 
 
 
 
 
 
 
38
  self.settings = new_settings
39
 
40
  function = new_settings.get("functionExpr", "").strip()
@@ -48,7 +54,8 @@ class OptimizationManager:
48
  "functionValues": {"x": [], "y": []},
49
  }
50
 
51
- self._reset_trajectory() # Must reset trajectory on any settings change that is valid
 
52
 
53
  if not self._function_changed(function, mode):
54
  return {
 
35
  if new_settings == self.settings:
36
  return None
37
 
38
+ non_relayout_settings = (new_settings.keys() | self.settings.keys()) - {"xlim", "ylim"}
39
+ non_relayout_settings_changed = any(
40
+ new_settings.get(k) != self.settings.get(k)
41
+ for k in non_relayout_settings
42
+ )
43
+
44
  self.settings = new_settings
45
 
46
  function = new_settings.get("functionExpr", "").strip()
 
54
  "functionValues": {"x": [], "y": []},
55
  }
56
 
57
+ if non_relayout_settings_changed:
58
+ self._reset_trajectory()
59
 
60
  if not self._function_changed(function, mode):
61
  return {
dist/assets/{index-QlirRdWU.js → index-DFkOm-gc.js} RENAMED
@@ -3843,4 +3843,4 @@ The plot is interactive:
3843
  - Click and drag to pan
3844
  - Scroll to zoom
3845
  - In bivariate mode, click **Update color scale** to rescale the heatmap so that the currently visible minimum and maximum values define the color range
3846
- `,ij={"Gradient Descent":{learningRate:"0.1",momentum:"0.0"},Nesterov:{learningRate:"0.1",momentum:"0.0"},Adam:{learningRate:"0.1",beta1:"0.9",beta2:"0.999",epsilon:"1e-8"},Adagrad:{learningRate:"0.1",epsilon:"1e-8"},RMSProp:{learningRate:"0.1",beta:"0.9",epsilon:"1e-8"},Adadelta:{beta:"0.9",epsilon:"1e-8"},Newton:{}},K6={"--Custom--":"x^2",Quadratic:"x^2",Cubic:"x^3 - 3x^2 + 2x",Quartic:"x^4 - 4x^3 + 6x^2 - 4x + 1",Sine:"sin(x)",Exponential:"exp(x)"},$6={"--Custom--":"x^2 + 3y^2",Quadratic:"x^2 + y^2",Ackley:"-20exp(-0.2 sqrt(0.5(x^2 + y^2))) - exp(0.5(cos(2 pi x) + cos(2 pi y))) + e + 20",Rasteringin:"20 + (x^2 - 10cos(2 pi x)) + (y^2 - 10cos(2 pi y))",Rosenbrock:"(1 - x)^2 + 100(y - x^2)^2"};function oj({settings:Ie,setSettings:ht,onRandomInitialPoint:St,trajectoryValues:wt,onReset:lr,onNextStep:vr,onPrevStep:Cr}){const nn=["Settings","Optimize","Usage"],[bn,Jr]=up.useState("Settings");function Tn(Fi,Ts){if(Fi==="algorithm"){const Mi=ij[Ts];ht({...Ie,algorithm:Ts,...Mi})}else ht({...Ie,[Fi]:Ts})}const[zn,_a]=up.useState("--Custom--");function Qn(Fi){_a(Fi);const Ts=Ie.mode==="Bivariate"?$6[Fi]:K6[Fi];Tn("functionExpr",Ts)}function fo(Fi){const Ts="--Custom--",Mi=Fi==="Bivariate"?$6[Ts]:K6[Ts];ht({...Ie,mode:Fi,functionExpr:Mi}),_a(Ts)}function So(Fi){return Fi&&Fi.length>0?Fi[Fi.length-1]:null}const Io=So(wt?.x),bi=So(wt?.y),Ge=So(wt?.derivative),ko=So(wt?.secondDerivative),Tl=So(wt?.z),Mo=So(wt?.gradient),yi=So(wt?.hessian);return zo.jsxs(J6,{className:"flex flex-col h-full p-4 gap-2 min-w-0 min-h-0 overflow-auto",children:[zo.jsx(DO,{tabs:nn,activeTab:bn,onChange:Jr}),zo.jsxs("div",{className:"flex flex-col gap-4 min-h-0 min-w-0 overflow-auto",children:[bn==="Settings"&&zo.jsxs(zo.Fragment,{children:[zo.jsx(IO,{label:"Problem Type",options:rj,activeOption:Ie.mode,onChange:fo}),zo.jsx(m8,{label:"Function",options:Ie.mode==="Bivariate"?Object.keys($6):Object.keys(K6),activeOption:zn,onChange:Qn}),zo.jsx(pd,{label:"Function Expression",value:Ie.functionExpr,onChange:Fi=>Tn("functionExpr",Fi),readonly:zn!=="--Custom--",rows:3}),zo.jsx(m8,{label:"Algorithm",options:nj,activeOption:Ie.algorithm,onChange:Fi=>Tn("algorithm",Fi)}),zo.jsxs("div",{className:`${Ie.mode==="Bivariate"?"grid grid-cols-2 gap-2":""}`,children:[zo.jsx(pd,{label:"Initial X",value:Ie.x0,onChange:Fi=>Tn("x0",Fi)}),Ie.mode==="Bivariate"&&zo.jsx(pd,{label:"Initial Y",value:Ie.y0||"",onChange:Fi=>Tn("y0",Fi)})]}),zo.jsx(ST,{label:"Random Initial Point",onClick:St}),zo.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[["Gradient Descent","Nesterov","Adam","Adagrad","RMSProp","Adadelta"].includes(Ie.algorithm)&&zo.jsx(zo.Fragment,{children:zo.jsx(pd,{label:"Learning Rate",value:Ie.learningRate,onChange:Fi=>Tn("learningRate",Fi)})}),["Gradient Descent","Nesterov"].includes(Ie.algorithm)&&zo.jsx(zo.Fragment,{children:zo.jsx(pd,{label:"Momentum",value:Ie.momentum,onChange:Fi=>Tn("momentum",Fi)})}),Ie.algorithm==="Adam"&&zo.jsxs(zo.Fragment,{children:[zo.jsx(pd,{label:"Beta 1",value:Ie.beta1,onChange:Fi=>Tn("beta1",Fi)}),zo.jsx(pd,{label:"Beta 2",value:Ie.beta2,onChange:Fi=>Tn("beta2",Fi)})]}),["RMSProp","Adadelta"].includes(Ie.algorithm)&&zo.jsx(zo.Fragment,{children:zo.jsx(pd,{label:"Beta",value:Ie.beta,onChange:Fi=>Tn("beta",Fi)})}),["Adam","Adagrad","RMSProp","Adadelta"].includes(Ie.algorithm)&&zo.jsx(zo.Fragment,{children:zo.jsx(pd,{label:"Epsilon",value:Ie.epsilon,onChange:Fi=>Tn("epsilon",Fi)})})]})]}),bn==="Optimize"&&zo.jsxs(zo.Fragment,{children:[zo.jsxs("div",{className:"hidden lg:flex flex-col gap-4 min-h-0 min-w-0",children:[Ie.mode==="Univariate"&&zo.jsxs(zo.Fragment,{children:[zo.jsx(pd,{label:"Current X",value:Io!==null?Io.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Y",value:bi!==null?bi.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Derivative",value:Ge!==null?Ge.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Second Derivative",value:ko!==null?ko.toFixed(4):"",readonly:!0})]}),Ie.mode==="Bivariate"&&zo.jsxs(zo.Fragment,{children:[zo.jsx(pd,{label:"Current X",value:Io!==null?Io.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Y",value:bi!==null?bi.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Z",value:Tl!==null?Tl.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Gradient",value:Mo!==null?`[${Mo.map(Fi=>Fi.toFixed(4)).join(", ")}]`:"",readonly:!0}),zo.jsx(pd,{label:"Current Hessian",value:yi!==null?`[${yi.map(Fi=>`[${Fi.map(Ts=>Ts.toFixed(4)).join(", ")}]`).join(", ")}]`:"",readonly:!0})]})]}),zo.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[zo.jsx(ST,{label:"Next Step",onClick:vr}),zo.jsx(ST,{label:"Previous Step",onClick:Cr})]}),zo.jsx(ST,{label:"Reset",onClick:lr})]}),bn==="Usage"&&zo.jsx($U,{components:{h1:({children:Fi})=>zo.jsx("h1",{className:"text-2xl font-bold mt-4 mb-2",children:Fi}),h2:({children:Fi})=>zo.jsx("h2",{className:"text-xl font-semibold mt-4 mb-2",children:Fi}),h3:({children:Fi})=>zo.jsx("h3",{className:"text-lg font-semibold mt-4 mb-2",children:Fi}),p:({children:Fi})=>zo.jsx("p",{className:"leading-6 mb-3 last:mb-0",children:Fi}),ul:({children:Fi})=>zo.jsx("ul",{className:"list-disc pl-5 mb-3",children:Fi}),ol:({children:Fi})=>zo.jsx("ol",{className:"list-decimal pl-5 mb-3",children:Fi}),li:({children:Fi})=>zo.jsx("li",{className:"mb-1",children:Fi})},children:aj})]})]})}function sj(Ie){return new Worker("/assets/pyodide.worker-CqQKSeoe.js",{name:Ie?.name})}function lj(Ie){const[ht,St]=up.useState({}),[wt,lr]=up.useState(!0),vr=up.useRef(null);function Cr(Tn){vr.current&&vr.current.postMessage({type:"INIT",settings:Tn})}function nn(){vr.current&&vr.current.postMessage({type:"NEXT_STEP"})}function bn(){vr.current&&vr.current.postMessage({type:"PREV_STEP"})}function Jr(){vr.current&&vr.current.postMessage({type:"RESET"})}return up.useEffect(()=>{const Tn=new sj;return vr.current=Tn,Tn.onmessage=zn=>{const _a=zn.data;_a.type==="READY"?(console.log("Pyodide is ready"),lr(!1),Cr(Ie)):_a.type==="RESULT"&&St(Qn=>({functionValues:_a.data.functionValues||Qn.functionValues,trajectoryValues:_a.data.trajectoryValues||Qn.trajectoryValues}))},()=>{Tn.terminate()}},[]),{isLoading:wt,plotData:ht,sendInit:Cr,sendReset:Jr,sendNextStep:nn,sendPrevStep:bn}}const uj={mode:"Univariate",functionExpr:"x^2",algorithm:"Gradient Descent",x0:"0.5",y0:"0.5",learningRate:"0.1",momentum:"0.0"},cj=[-1,1],fj=[-1,1];function hj(){const[Ie,ht]=up.useState(uj),St=up.useRef(cj),wt=up.useRef(fj),lr={...Ie,xlim:St.current,ylim:wt.current};function vr(Jr){ht(Jr),bn.sendInit({...Jr,xlim:St.current,ylim:wt.current})}function Cr(Jr,Tn){St.current=Jr,wt.current=Tn,bn.sendInit({...Ie,xlim:Jr,ylim:Tn})}function nn(){const Jr=St.current[1]-St.current[0],Tn=wt.current[1]-wt.current[0],zn=(St.current[0]+Math.random()*Jr*.95).toFixed(2),_a=(wt.current[0]+Math.random()*Tn*.95).toFixed(2),Qn={...Ie,x0:zn,y0:_a};vr(Qn)}const bn=lj(lr);return zo.jsxs("div",{className:"grid grid-cols-[1fr_12fr_1fr] lg:h-dvh bg-stone-50",children:[zo.jsx("div",{}),zo.jsxs("div",{className:"flex flex-col gap-6 p-6 min-h-0",children:[zo.jsx("div",{className:"title",children:"Optimization Trajectory Visualizer"}),zo.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[2fr_1fr] gap-12 flex-1 min-h-0 overflow-auto",children:[zo.jsx(zO,{data:bn.plotData,xlim:St.current,ylim:wt.current,setAxisLimits:Cr}),zo.jsx(oj,{settings:Ie,setSettings:vr,onRandomInitialPoint:nn,trajectoryValues:bn.plotData.trajectoryValues,onReset:()=>bn.sendReset(),onNextStep:()=>bn.sendNextStep(),onPrevStep:()=>bn.sendPrevStep()})]})]}),zo.jsx("div",{})]})}AO.createRoot(document.getElementById("root")).render(zo.jsx(up.StrictMode,{children:zo.jsx(hj,{})}));
 
3843
  - Click and drag to pan
3844
  - Scroll to zoom
3845
  - In bivariate mode, click **Update color scale** to rescale the heatmap so that the currently visible minimum and maximum values define the color range
3846
+ `,ij={"Gradient Descent":{learningRate:"0.1",momentum:"0.0"},Nesterov:{learningRate:"0.1",momentum:"0.0"},Adam:{learningRate:"0.1",beta1:"0.9",beta2:"0.999",epsilon:"1e-8"},Adagrad:{learningRate:"0.1",epsilon:"1e-8"},RMSProp:{learningRate:"0.1",beta:"0.9",epsilon:"1e-8"},Adadelta:{beta:"0.9",epsilon:"1e-8"},Newton:{}},K6={"--Custom--":"x^2",Quadratic:"x^2",Cubic:"x^3 - 3x^2 + 2x",Quartic:"x^4 - 4x^3 + 6x^2 - 4x + 1",Sine:"sin(x)",Exponential:"exp(x)"},$6={"--Custom--":"x^2 + 3y^2",Quadratic:"x^2 + y^2",Ackley:"-20exp(-0.2 sqrt(0.5(x^2 + y^2))) - exp(0.5(cos(2 pi x) + cos(2 pi y))) + e + 20",Rasteringin:"20 + (x^2 - 10cos(2 pi x)) + (y^2 - 10cos(2 pi y))",Rosenbrock:"(1 - x)^2 + 100(y - x^2)^2"};function oj({settings:Ie,setSettings:ht,onRandomInitialPoint:St,trajectoryValues:wt,onReset:lr,onNextStep:vr,onPrevStep:Cr}){const nn=["Settings","Optimize","Usage"],[bn,Jr]=up.useState("Settings");function Tn(Fi,Ts){if(Fi==="algorithm"){const Mi=ij[Ts];ht({...Ie,algorithm:Ts,...Mi})}else ht({...Ie,[Fi]:Ts})}const[zn,_a]=up.useState("--Custom--");function Qn(Fi){_a(Fi);const Ts=Ie.mode==="Bivariate"?$6[Fi]:K6[Fi];Tn("functionExpr",Ts)}function fo(Fi){const Ts="--Custom--",Mi=Fi==="Bivariate"?$6[Ts]:K6[Ts];ht({...Ie,mode:Fi,functionExpr:Mi}),_a(Ts)}function So(Fi){return Fi&&Fi.length>0?Fi[Fi.length-1]:null}const Io=So(wt?.x),bi=So(wt?.y),Ge=So(wt?.derivative),ko=So(wt?.secondDerivative),Tl=So(wt?.z),Mo=So(wt?.gradient),yi=So(wt?.hessian);return zo.jsxs(J6,{className:"flex flex-col h-full p-4 gap-2 min-w-0 min-h-0 overflow-auto",children:[zo.jsx(DO,{tabs:nn,activeTab:bn,onChange:Jr}),zo.jsxs("div",{className:"flex flex-col gap-4 min-h-0 min-w-0 overflow-auto",children:[bn==="Settings"&&zo.jsxs(zo.Fragment,{children:[zo.jsx(IO,{label:"Problem Type",options:rj,activeOption:Ie.mode,onChange:fo}),zo.jsx(m8,{label:"Function",options:Ie.mode==="Bivariate"?Object.keys($6):Object.keys(K6),activeOption:zn,onChange:Qn}),zo.jsx(pd,{label:"Function Expression",value:Ie.functionExpr,onChange:Fi=>Tn("functionExpr",Fi),readonly:zn!=="--Custom--",rows:3}),zo.jsx(m8,{label:"Algorithm",options:nj,activeOption:Ie.algorithm,onChange:Fi=>Tn("algorithm",Fi)}),zo.jsxs("div",{className:`${Ie.mode==="Bivariate"?"grid grid-cols-2 gap-2":""}`,children:[zo.jsx(pd,{label:"Initial X",value:Ie.x0,onChange:Fi=>Tn("x0",Fi)}),Ie.mode==="Bivariate"&&zo.jsx(pd,{label:"Initial Y",value:Ie.y0||"",onChange:Fi=>Tn("y0",Fi)})]}),zo.jsx(ST,{label:"Random Initial Point",onClick:St}),zo.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[["Gradient Descent","Nesterov","Adam","Adagrad","RMSProp","Adadelta"].includes(Ie.algorithm)&&zo.jsx(zo.Fragment,{children:zo.jsx(pd,{label:"Learning Rate",value:Ie.learningRate,onChange:Fi=>Tn("learningRate",Fi)})}),["Gradient Descent","Nesterov"].includes(Ie.algorithm)&&zo.jsx(zo.Fragment,{children:zo.jsx(pd,{label:"Momentum",value:Ie.momentum,onChange:Fi=>Tn("momentum",Fi)})}),Ie.algorithm==="Adam"&&zo.jsxs(zo.Fragment,{children:[zo.jsx(pd,{label:"Beta 1",value:Ie.beta1,onChange:Fi=>Tn("beta1",Fi)}),zo.jsx(pd,{label:"Beta 2",value:Ie.beta2,onChange:Fi=>Tn("beta2",Fi)})]}),["RMSProp","Adadelta"].includes(Ie.algorithm)&&zo.jsx(zo.Fragment,{children:zo.jsx(pd,{label:"Beta",value:Ie.beta,onChange:Fi=>Tn("beta",Fi)})}),["Adam","Adagrad","RMSProp","Adadelta"].includes(Ie.algorithm)&&zo.jsx(zo.Fragment,{children:zo.jsx(pd,{label:"Epsilon",value:Ie.epsilon,onChange:Fi=>Tn("epsilon",Fi)})})]})]}),bn==="Optimize"&&zo.jsxs(zo.Fragment,{children:[zo.jsxs("div",{className:"hidden lg:flex flex-col gap-4 min-h-0 min-w-0",children:[Ie.mode==="Univariate"&&zo.jsxs(zo.Fragment,{children:[zo.jsx(pd,{label:"Current X",value:Io!==null?Io.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Y",value:bi!==null?bi.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Derivative",value:Ge!==null?Ge.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Second Derivative",value:ko!==null?ko.toFixed(4):"",readonly:!0})]}),Ie.mode==="Bivariate"&&zo.jsxs(zo.Fragment,{children:[zo.jsx(pd,{label:"Current X",value:Io!==null?Io.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Y",value:bi!==null?bi.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Z",value:Tl!==null?Tl.toFixed(4):"",readonly:!0}),zo.jsx(pd,{label:"Current Gradient",value:Mo!==null?`[${Mo.map(Fi=>Fi.toFixed(4)).join(", ")}]`:"",readonly:!0}),zo.jsx(pd,{label:"Current Hessian",value:yi!==null?`[${yi.map(Fi=>`[${Fi.map(Ts=>Ts.toFixed(4)).join(", ")}]`).join(", ")}]`:"",readonly:!0})]})]}),zo.jsxs("div",{className:"grid grid-cols-2 gap-2",children:[zo.jsx(ST,{label:"Next Step",onClick:vr}),zo.jsx(ST,{label:"Previous Step",onClick:Cr})]}),zo.jsx(ST,{label:"Reset",onClick:lr})]}),bn==="Usage"&&zo.jsx($U,{components:{h1:({children:Fi})=>zo.jsx("h1",{className:"text-2xl font-bold mt-4 mb-2",children:Fi}),h2:({children:Fi})=>zo.jsx("h2",{className:"text-xl font-semibold mt-4 mb-2",children:Fi}),h3:({children:Fi})=>zo.jsx("h3",{className:"text-lg font-semibold mt-4 mb-2",children:Fi}),p:({children:Fi})=>zo.jsx("p",{className:"leading-6 mb-3 last:mb-0",children:Fi}),ul:({children:Fi})=>zo.jsx("ul",{className:"list-disc pl-5 mb-3",children:Fi}),ol:({children:Fi})=>zo.jsx("ol",{className:"list-decimal pl-5 mb-3",children:Fi}),li:({children:Fi})=>zo.jsx("li",{className:"mb-1",children:Fi})},children:aj})]})]})}function sj(Ie){return new Worker("/assets/pyodide.worker-BFXTvOBt.js",{name:Ie?.name})}function lj(Ie){const[ht,St]=up.useState({}),[wt,lr]=up.useState(!0),vr=up.useRef(null);function Cr(Tn){vr.current&&vr.current.postMessage({type:"INIT",settings:Tn})}function nn(){vr.current&&vr.current.postMessage({type:"NEXT_STEP"})}function bn(){vr.current&&vr.current.postMessage({type:"PREV_STEP"})}function Jr(){vr.current&&vr.current.postMessage({type:"RESET"})}return up.useEffect(()=>{const Tn=new sj;return vr.current=Tn,Tn.onmessage=zn=>{const _a=zn.data;_a.type==="READY"?(console.log("Pyodide is ready"),lr(!1),Cr(Ie)):_a.type==="RESULT"&&St(Qn=>({functionValues:_a.data.functionValues||Qn.functionValues,trajectoryValues:_a.data.trajectoryValues||Qn.trajectoryValues}))},()=>{Tn.terminate()}},[]),{isLoading:wt,plotData:ht,sendInit:Cr,sendReset:Jr,sendNextStep:nn,sendPrevStep:bn}}const uj={mode:"Univariate",functionExpr:"x^2",algorithm:"Gradient Descent",x0:"0.5",y0:"0.5",learningRate:"0.1",momentum:"0.0"},cj=[-1,1],fj=[-1,1];function hj(){const[Ie,ht]=up.useState(uj),St=up.useRef(cj),wt=up.useRef(fj),lr={...Ie,xlim:St.current,ylim:wt.current};function vr(Jr){ht(Jr),bn.sendInit({...Jr,xlim:St.current,ylim:wt.current})}function Cr(Jr,Tn){St.current=Jr,wt.current=Tn,bn.sendInit({...Ie,xlim:Jr,ylim:Tn})}function nn(){const Jr=St.current[1]-St.current[0],Tn=wt.current[1]-wt.current[0],zn=(St.current[0]+Math.random()*Jr*.95).toFixed(2),_a=(wt.current[0]+Math.random()*Tn*.95).toFixed(2),Qn={...Ie,x0:zn,y0:_a};vr(Qn)}const bn=lj(lr);return zo.jsxs("div",{className:"grid grid-cols-[1fr_12fr_1fr] lg:h-dvh bg-stone-50",children:[zo.jsx("div",{}),zo.jsxs("div",{className:"flex flex-col gap-6 p-6 min-h-0",children:[zo.jsx("div",{className:"title",children:"Optimization Trajectory Visualizer"}),zo.jsxs("div",{className:"grid grid-cols-1 lg:grid-cols-[2fr_1fr] gap-12 flex-1 min-h-0 overflow-auto",children:[zo.jsx(zO,{data:bn.plotData,xlim:St.current,ylim:wt.current,setAxisLimits:Cr}),zo.jsx(oj,{settings:Ie,setSettings:vr,onRandomInitialPoint:nn,trajectoryValues:bn.plotData.trajectoryValues,onReset:()=>bn.sendReset(),onNextStep:()=>bn.sendNextStep(),onPrevStep:()=>bn.sendPrevStep()})]})]}),zo.jsx("div",{})]})}AO.createRoot(document.getElementById("root")).render(zo.jsx(up.StrictMode,{children:zo.jsx(hj,{})}));
dist/assets/{pyodide.worker-CqQKSeoe.js → pyodide.worker-BFXTvOBt.js} RENAMED
@@ -35,6 +35,12 @@ class OptimizationManager:
35
  if new_settings == self.settings:
36
  return None
37
 
 
 
 
 
 
 
38
  self.settings = new_settings
39
 
40
  function = new_settings.get("functionExpr", "").strip()
@@ -48,7 +54,8 @@ class OptimizationManager:
48
  "functionValues": {"x": [], "y": []},
49
  }
50
 
51
- self._reset_trajectory() # Must reset trajectory on any settings change that is valid
 
52
 
53
  if not self._function_changed(function, mode):
54
  return {
 
35
  if new_settings == self.settings:
36
  return None
37
 
38
+ non_relayout_settings = (new_settings.keys() | self.settings.keys()) - {"xlim", "ylim"}
39
+ non_relayout_settings_changed = any(
40
+ new_settings.get(k) != self.settings.get(k)
41
+ for k in non_relayout_settings
42
+ )
43
+
44
  self.settings = new_settings
45
 
46
  function = new_settings.get("functionExpr", "").strip()
 
54
  "functionValues": {"x": [], "y": []},
55
  }
56
 
57
+ if non_relayout_settings_changed:
58
+ self._reset_trajectory()
59
 
60
  if not self._function_changed(function, mode):
61
  return {
dist/index.html CHANGED
@@ -5,7 +5,7 @@
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>Optimization</title>
8
- <script type="module" crossorigin src="/assets/index-QlirRdWU.js"></script>
9
  <link rel="stylesheet" crossorigin href="/assets/index-CoMlohDF.css">
10
  </head>
11
  <body>
 
5
  <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
  <title>Optimization</title>
8
+ <script type="module" crossorigin src="/assets/index-DFkOm-gc.js"></script>
9
  <link rel="stylesheet" crossorigin href="/assets/index-CoMlohDF.css">
10
  </head>
11
  <body>