7272 bPhibb <- cpp_quadratic_form_sym(b , Phi ) # b'Phi*b
7373 bAb <- cpp_quadratic_form_sym(b , A ) # b'A*b
7474
75+ # Ensure positive quadratic form (eigenvector sign is arbitrary)
76+ if (bPhibb < 0 ) {
77+ b <- - b
78+ bPhibb <- - bPhibb
79+ }
80+
7581 sigma_I <- if (bPhibb > 0 ) sqrt(bPhibb ) else NA_real_
7682
7783 # Selection response: R = k_I * sigma_I
97103 rHI <- if (! is.na(hI2 ) && hI2 > = 0 ) sqrt(hI2 ) else NA_real_
98104
99105 list (
106+ b = b , # Return corrected eigenvector
100107 bPhibb = bPhibb ,
101108 bAb = bAb ,
102109 sigma_I = sigma_I ,
@@ -314,17 +321,20 @@ mesim <- function(pmat, gmat, S_M, S_Mg = NULL, S_var = NULL, selection_intensit
314321 lambda2 <- ev_result $ value
315322 b_M <- ev_result $ vector
316323
317- # Split into phenotype and marker coefficients
318- b_y <- b_M [1 : n_traits ]
319- b_s <- b_M [(n_traits + 1 ): (2 * n_traits )]
320-
321324 # --------------------------------------------------------------------------
322325 # Step 3: Compute metrics using combined matrices
323326 # --------------------------------------------------------------------------
324327 metrics <- .genomic_eigen_index_metrics(b_M , T_M , Psi_M ,
325328 lambda2 = lambda2 ,
326329 k_I = selection_intensity )
327330
331+ # Extract corrected eigenvector (sign-corrected for positive quadratic form)
332+ b_M <- metrics $ b
333+
334+ # Split into phenotype and marker score coefficients
335+ b_y <- b_M [1 : n_traits ]
336+ b_s <- b_M [(n_traits + 1 ): (2 * n_traits )]
337+
328338 # Expected gains are first n_traits elements of E_vec
329339 E_M <- metrics $ E_vec [1 : n_traits ]
330340 names(E_M ) <- trait_names
@@ -495,17 +505,20 @@ gesim <- function(pmat, gmat, Gamma, selection_intensity = 2.063) {
495505 lambda2 <- ev_result $ value
496506 b_G <- ev_result $ vector
497507
498- # Split into phenotype and GEBV coefficients
499- b_y <- b_G [1 : n_traits ]
500- b_gamma <- b_G [(n_traits + 1 ): (2 * n_traits )]
501-
502508 # --------------------------------------------------------------------------
503509 # Step 3: Compute metrics
504510 # --------------------------------------------------------------------------
505511 metrics <- .genomic_eigen_index_metrics(b_G , Phi , A ,
506512 lambda2 = lambda2 ,
507513 k_I = selection_intensity )
508514
515+ # Extract corrected eigenvector (sign-corrected for positive quadratic form)
516+ b_G <- metrics $ b
517+
518+ # Split into phenotype and GEBV coefficients
519+ b_y <- b_G [1 : n_traits ]
520+ b_gamma <- b_G [(n_traits + 1 ): (2 * n_traits )]
521+
509522 # Expected gains are first n_traits elements
510523 E_G <- metrics $ E_vec [1 : n_traits ]
511524 names(E_G ) <- trait_names
@@ -609,8 +622,8 @@ gesim <- function(pmat, gmat, Gamma, selection_intensity = 2.063) {
609622# ' \deqn{(\mathbf{Q}^{-1}\mathbf{X} - \lambda_W^2 \mathbf{I}_{(t+N)})\boldsymbol{\beta}_W = 0}
610623# '
611624# ' where:
612- # ' \deqn{\mathbf{Q} = \begin{bmatrix} \mathbf{P} & \mathbf{G}_M^{\prime} \\ \mathbf{G}_M & \mathbf{M} \end{bmatrix}}
613- # ' \deqn{\mathbf{X} = \begin{bmatrix} \mathbf{C} & \mathbf{G}_M^{\prime} \\ \mathbf{G}_M & \mathbf{M} \end{bmatrix}}
625+ # ' \deqn{\mathbf{Q} = \begin{bmatrix} \mathbf{P} & \mathbf{G}_M \\ \mathbf{G}_M^{\prime} & \mathbf{M} \end{bmatrix}}
626+ # ' \deqn{\mathbf{X} = \begin{bmatrix} \mathbf{C} & \mathbf{G}_M \\ \mathbf{G}_M^{\prime} & \mathbf{M} \end{bmatrix}}
614627# '
615628# ' \strong{Selection response:}
616629# ' \deqn{R_W = k_I \sqrt{\boldsymbol{\beta}_W^{\prime}\mathbf{Q}\boldsymbol{\beta}_W}}
@@ -673,18 +686,18 @@ gw_esim <- function(pmat, gmat, G_M, M, selection_intensity = 2.063) {
673686 # --------------------------------------------------------------------------
674687 # Step 1: Construct combined matrices Q and X
675688 # --------------------------------------------------------------------------
676- # Q = [P G_M' ]
677- # [G_M M ]
689+ # Q = [P G_M ]
690+ # [G_M' M ]
678691 Q <- rbind(
679- cbind(pmat , t( G_M ) ),
680- cbind(G_M , M )
692+ cbind(pmat , G_M ),
693+ cbind(t( G_M ), M )
681694 )
682695
683- # X = [C G_M' ]
684- # [G_M M ]
696+ # X = [C G_M ]
697+ # [G_M' M ]
685698 X <- rbind(
686- cbind(gmat , t( G_M ) ),
687- cbind(G_M , M )
699+ cbind(gmat , G_M ),
700+ cbind(t( G_M ), M )
688701 )
689702
690703 # --------------------------------------------------------------------------
@@ -696,17 +709,20 @@ gw_esim <- function(pmat, gmat, G_M, M, selection_intensity = 2.063) {
696709 lambda2 <- ev_result $ value
697710 b_W <- ev_result $ vector
698711
699- # Split into phenotype and marker coefficients
700- b_y <- b_W [1 : n_traits ]
701- b_m <- b_W [(n_traits + 1 ): (n_traits + n_markers )]
702-
703712 # --------------------------------------------------------------------------
704713 # Step 3: Compute metrics
705714 # --------------------------------------------------------------------------
706715 metrics <- .genomic_eigen_index_metrics(b_W , Q , X ,
707716 lambda2 = lambda2 ,
708717 k_I = selection_intensity )
709718
719+ # Extract corrected eigenvector (sign-corrected for positive quadratic form)
720+ b_W <- metrics $ b
721+
722+ # Split into phenotype and marker coefficients
723+ b_y <- b_W [1 : n_traits ]
724+ b_m <- b_W [(n_traits + 1 ): (n_traits + n_markers )]
725+
710726 # Expected gains are first n_traits elements
711727 E_W <- metrics $ E_vec [1 : n_traits ]
712728 names(E_W ) <- trait_names
@@ -878,12 +894,9 @@ rgesim <- function(pmat, gmat, Gamma, U_mat, selection_intensity = 2.063) {
878894 # 2. The GEBV coefficient b_gamma[i] (row t+i)
879895 # Otherwise, the index bypasses the restriction by shifting weight to GEBV.
880896 #
881- # If U_mat restricts trait i (has 1 in row i), then U_G must have:
882- # - 1 in row i (phenotype)
883- # - 1 in row t+i (GEBV)
884- #
885- # Solution: Stack U_mat twice to create (2t x r) restriction matrix
886- U_G <- rbind(U_mat , U_mat ) # [U_mat; U_mat] ensures both y and gamma are restricted
897+ # Solution: Concatenate U_mat horizontally to create (r x 2t) restriction matrix
898+ # This applies each constraint to both phenotype and GEBV coefficients
899+ U_G <- cbind(U_mat , U_mat ) # [U_mat, U_mat] ensures both y and gamma are restricted
887900
888901 # --------------------------------------------------------------------------
889902 # Step 2: Compute constraint projection matrix Q_RG
@@ -913,17 +926,20 @@ rgesim <- function(pmat, gmat, Gamma, U_mat, selection_intensity = 2.063) {
913926 lambda2 <- ev_result $ value
914927 b_RG <- ev_result $ vector
915928
916- # Split coefficients
917- b_y <- b_RG [1 : n_traits ]
918- b_gamma <- b_RG [(n_traits + 1 ): (2 * n_traits )]
919-
920929 # --------------------------------------------------------------------------
921930 # Step 4: Compute metrics
922931 # --------------------------------------------------------------------------
923932 metrics <- .genomic_eigen_index_metrics(b_RG , Phi , A ,
924933 lambda2 = lambda2 ,
925934 k_I = selection_intensity )
926935
936+ # Extract corrected eigenvector (sign-corrected for positive quadratic form)
937+ b_RG <- metrics $ b
938+
939+ # Split coefficients
940+ b_y <- b_RG [1 : n_traits ]
941+ b_gamma <- b_RG [(n_traits + 1 ): (2 * n_traits )]
942+
927943 E_RG <- metrics $ E_vec [1 : n_traits ]
928944 names(E_RG ) <- trait_names
929945
@@ -1173,17 +1189,20 @@ ppg_gesim <- function(pmat, gmat, Gamma, d, selection_intensity = 2.063) {
11731189 lambda2 <- ev_result $ value
11741190 b_PG <- ev_result $ vector
11751191
1176- # Split coefficients
1177- b_y <- b_PG [1 : n_traits ]
1178- b_gamma <- b_PG [(n_traits + 1 ): (2 * n_traits )]
1179-
11801192 # --------------------------------------------------------------------------
11811193 # Step 6: Compute metrics
11821194 # --------------------------------------------------------------------------
11831195 metrics <- .genomic_eigen_index_metrics(b_PG , Phi , A ,
11841196 lambda2 = lambda2 ,
11851197 k_I = selection_intensity )
11861198
1199+ # Extract corrected eigenvector (sign-corrected for positive quadratic form)
1200+ b_PG <- metrics $ b
1201+
1202+ # Split coefficients
1203+ b_y <- b_PG [1 : n_traits ]
1204+ b_gamma <- b_PG [(n_traits + 1 ): (2 * n_traits )]
1205+
11871206 E_PG <- metrics $ E_vec [1 : n_traits ]
11881207 names(E_PG ) <- trait_names
11891208
0 commit comments