function [Xden, stats] = tt_cp_denoise_keep(P, components_keep)
    assert(isa(P,'ktensor') && ndims(P)==3, ...
        'P must be a 3-way Tensor Toolbox ktensor (neurons x time x trials).');

    % -------- Factor unpack --------
    A = double(P.U{1});   % neurons (N x R)
    B = double(P.U{2});   % time    (T x R)
    C = double(P.U{3});   % trials  (Tr x R)
    lam = double(P.lambda(:));   % (R x 1)
    [N, R] = size(A); T = size(B,1); Tr = size(C,1);

    K = unique(components_keep(:)');
    K = K(K>=1 & K<=R);
    assert(~isempty(K), 'components_keep must contain indices in 1..%d', R);

    % -------- FULL dense reconstruction (streaming over components) --------
    Xden = zeros(N, T, Tr, 'like', A);
    for kk = K
        % rank-1 block for component kk across neurons x time
        M = lam(kk) * (A(:,kk) * B(:,kk).');   % (N x T)
        % expand across trials with C(:,kk)
        % X(:,:,t) += C(t,kk) * M
        Xden = Xden + bsxfun(@times, M, reshape(C(:,kk), 1, 1, Tr));
    end

    % -------- Quality metrics vs ALL components (no full “all” build) --------
    % Energy (Frobenius) of a CP is computable from Gram matrices:
    % ||Σ_k λ_k a_k∘b_k∘c_k||_F^2 = Σ_{i,j} λ_i λ_j (a_i·a_j)(b_i·b_j)(c_i·c_j)
    G_A = A.'*A;   % (R x R)
    G_B = B.'*B;
    G_C = C.'*C;

    lam_all = lam;                 % all comps
    lam_keep = zeros(R,1); lam_keep(K) = lam(K);

    % helper: energy = lam' * (G_A ∘ G_B ∘ G_C) * lam
    H = G_A .* G_B .* G_C;         % Hadamard (R x R)
    e_all  = lam_all.'  * (H * lam_all);        % ||ALL||_F^2
    e_keep = lam_keep.' * (H * lam_keep);       % ||KEEP||_F^2
    e_res  = max(e_all - e_keep, 0);            % ||residual||_F^2 (numerical safety)

    energy_R2_vs_all = (e_all==0) * 0 + (e_all>0) * (e_keep / e_all);  % ∈[0,1]

    stats = struct();
    stats.rank_all   = R;
    stats.rank_keep  = numel(K);
    stats.keep_idx   = K;
    stats.energy_all = e_all;
    stats.energy_keep= e_keep;
    stats.energy_res = e_res;
    stats.energy_R2_vs_all = energy_R2_vs_all;  % fraction of energy kept
end
