@@ -798,10 +798,26 @@ class SeroJumpApp {
798798 const thinningInterval = 10 ; // Only store every 10th sample
799799 let sampleCount = 0 ;
800800
801+ // Plot data limits for performance
802+ const maxPlotPoints = 1000 ; // Maximum points to show in plots
803+ const maxTracePoints = 500 ; // Maximum points per trace
804+
805+ // Performance mode for very long runs
806+ const performanceMode = mcmcSteps > 10000 ;
807+ const plotUpdateInterval = performanceMode ? 200 : 100 ; // Less frequent updates for long runs
808+
801809 // Performance tracking
802810 const startTime = Date . now ( ) ;
803811 let lastProgressTime = startTime ;
804812
813+ // Helper function to limit array size for performance
814+ const limitArraySize = ( arr , maxSize ) => {
815+ if ( arr . length > maxSize ) {
816+ return arr . slice ( - maxSize ) ; // Keep only the last maxSize elements
817+ }
818+ return arr ;
819+ } ;
820+
805821 // Run MCMC iterations
806822 for ( let step = 0 ; step < mcmcSteps ; step ++ ) {
807823 // Run MCMC step for all chains in parallel
@@ -825,8 +841,8 @@ class SeroJumpApp {
825841 // Update visualization if past burn-in (use first chain for display)
826842 if ( step >= burninSteps && chainId === 0 ) {
827843 this . updateIndividualCard ( individual , result ) ;
828- // Update plots only every 200 steps for performance
829- if ( step % 200 === 0 ) {
844+ // Update plots with performance-aware frequency
845+ if ( step % plotUpdateInterval === 0 ) {
830846 this . plotIndividualTrajectory ( individual , result ) ;
831847 }
832848 }
@@ -891,28 +907,56 @@ class SeroJumpApp {
891907 combinedPosteriorSamples . boost . push ( chain . posteriorSamples . boost [ chain . posteriorSamples . boost . length - 1 ] ) ;
892908 }
893909
894- // Update plots every 200 steps (reduced frequency)
895- if ( step % 200 === 0 ) {
896- this . plotTotalInfections ( combinedPosteriorInfectionCounts , trueInfections ) ;
897- this . plotIndividualProbabilities ( combinedIndividualInfectionProbs ) ;
910+ // Update plots with performance-aware frequency
911+ if ( step % plotUpdateInterval === 0 ) {
912+ // Limit data size for performance
913+ const limitedInfectionCounts = limitArraySize ( combinedPosteriorInfectionCounts , maxPlotPoints ) ;
914+ const limitedIndividualProbs = { } ;
915+ for ( const [ id , probs ] of Object . entries ( combinedIndividualInfectionProbs ) ) {
916+ limitedIndividualProbs [ id ] = limitArraySize ( probs , maxTracePoints ) ;
917+ }
918+
919+ this . plotTotalInfections ( limitedInfectionCounts , trueInfections ) ;
920+ this . plotIndividualProbabilities ( limitedIndividualProbs ) ;
898921 }
899922
900923 // Update convergence diagnostics every 500 steps (reduced frequency)
901924 if ( step % 500 === 0 ) {
902- this . updateConvergenceDiagnostics ( chains , step , burninSteps ) ;
925+ // Limit chain data for performance
926+ const limitedChains = chains . map ( chain => ( {
927+ ...chain ,
928+ posteriorSamples : {
929+ baseline : limitArraySize ( chain . posteriorSamples . baseline , maxTracePoints ) ,
930+ boost : limitArraySize ( chain . posteriorSamples . boost , maxTracePoints ) ,
931+ infectionCounts : limitArraySize ( chain . posteriorSamples . infectionCounts , maxTracePoints ) ,
932+ infectionTimes : limitArraySize ( chain . posteriorSamples . infectionTimes , maxTracePoints )
933+ } ,
934+ iterationNumbers : limitArraySize ( chain . iterationNumbers , maxTracePoints )
935+ } ) ) ;
936+ this . updateConvergenceDiagnostics ( limitedChains , step , burninSteps ) ;
903937 }
904938
905939 // Update posterior analysis every 500 steps (reduced frequency)
906940 if ( step % 500 === 0 ) {
907- this . updatePosteriorAnalysis ( combinedPosteriorSamples , combinedTimingPosteriorSamples ) ;
941+ // Limit posterior samples for performance
942+ const limitedPosteriorSamples = {
943+ baseline : limitArraySize ( combinedPosteriorSamples . baseline , maxTracePoints ) ,
944+ boost : limitArraySize ( combinedPosteriorSamples . boost , maxTracePoints ) ,
945+ infectionTimes : limitArraySize ( combinedPosteriorSamples . infectionTimes , maxTracePoints )
946+ } ;
947+ const limitedTimingSamples = { } ;
948+ for ( const [ id , times ] of Object . entries ( combinedTimingPosteriorSamples ) ) {
949+ limitedTimingSamples [ id ] = limitArraySize ( times , maxTracePoints ) ;
950+ }
951+ this . updatePosteriorAnalysis ( limitedPosteriorSamples , limitedTimingSamples ) ;
908952 }
909953 }
910954
911955 // Increment sample count for thinning
912956 sampleCount ++ ;
913957
914958 // Update progress after processing all chains (throttled)
915- if ( step % 50 === 0 || step === mcmcSteps - 1 ) {
959+ if ( step % 25 === 0 || step === mcmcSteps - 1 ) {
916960 const currentTime = Date . now ( ) ;
917961 const elapsedTime = currentTime - startTime ;
918962 const stepsPerSecond = ( step + 1 ) / ( elapsedTime / 1000 ) ;
0 commit comments