K-Wave Bug: Fixing Incompatible Size Error In Examples

by Admin 55 views
K-Wave Bug: Fixing Incompatible Size Error in Examples

Hey guys,

Are you new to k-Wave and running into the dreaded "incompatible size error" when trying to run those nifty examples with MATLAB R2025b? Don't worry, you're not alone! This article dives into a common bug encountered while using kspaceFirstOrder2D and provides a workaround to get those simulations up and running. Let's get started!

What's the Issue?

Specifically, the error pops up when running examples like example_ivp_homogeneous_medium.m. The error message usually looks something like this:

Arrays have incompatible sizes for this operation.

Error in kspaceFirstOrder2D (line 920)
        ux_sgx = dt .* rho0_sgx_inv .* real(ifft2( bsxfun(@times, ddx_k_shift_pos, kappa .* fft2(p)) )) / 2;
                                                                                         ^
Error in example_ivp_homogeneous_medium (line 67)
sensor_data = kspaceFirstOrder2D(kgrid, medium, source, sensor);

This error stems from size mismatches within the kspaceFirstOrder2D function, particularly when dealing with the FFT (Fast Fourier Transform) operations. Let's break down how to tackle this problem.

The Root Cause

The issue seems to be related to how the code handles grid smoothing and expansion, especially in the kspaceFirstOrder_inputChecking.m and kspaceSecondOrder.m files.

kspaceFirstOrder_inputChecking.m

In the kspaceFirstOrder_inputChecking.m file, the smooth function within the "Smooth and enlarge grids" section (around line 1488) can cause problems. This section deals with creating expanded radial grids when using axisymmetric simulations.

    if flags.axisymmetric
        switch radial_symmetry
            case {'WSWA-FFT', 'WSWA'}

                % create a new kWave grid object with expanded radial grid
                kgrid_exp = kWaveGrid(kgrid.Nx, kgrid.dx, kgrid.Ny * 4, kgrid.dy);                 
                
                % mirror p0 in radial dimension using WSWA symmetry 
                p0_exp = zeros(kgrid_exp.Nx, kgrid_exp.Ny);
                p0_exp(:, kgrid.Ny*0 + 1:kgrid.Ny*1) =         source.p0;
                p0_exp(:, kgrid.Ny*1 + 2:kgrid.Ny*2) = -fliplr(source.p0(:, 2:end));
                p0_exp(:, kgrid.Ny*2 + 1:kgrid.Ny*3) =        -source.p0;
                p0_exp(:, kgrid.Ny*3 + 2:kgrid.Ny*4) =  fliplr(source.p0(:, 2:end));

            case {'WSWS-FFT', 'WSWS'}

                % create a new kWave grid object with expanded radial grid
                kgrid_exp = kWaveGrid(kgrid.Nx, kgrid.dx, kgrid.Ny * 2 - 2, kgrid.dy);                  
                
                % mirror p0 in radial dimension using WSWS symmetry 
                p0_exp = zeros(kgrid_exp.Nx, kgrid_exp.Ny);
                p0_exp(:,            1:kgrid.Ny)       =        source.p0;
                p0_exp(:, kgrid.Ny + 1:kgrid.Ny*2 - 2) = fliplr(source.p0(:, 2:end - 1));
                
        end

        % clean up unused variables
        clear kgrid_exp p0_exp;
    end

kspaceSecondOrder.m

Similarly, in kspaceSecondOrder.m, the section "Calculate FFT of source functions and expand grid" (around line 328) might also contribute to size incompatibility issues.

% =========================================================================
% CALCULATE FFT OF SOURCE FUNCTIONS AND EXPAND GRID
% =========================================================================

if ~expand_grid 
    
    % extract wavenumber matrix from kgrid
    k = kgrid.k;
    
    % extract the location of the sensor points
    sensor_index = (sensor.mask == 1);
    
    % compute FFT of source functions
    if source_case ~= 2
        p0_k = fftn(source.p0);
    end
    if source_case > 1
        dp0dt_k = fftn(source.dp0dt);
    end
    
else

The Solution: A Temporary Workaround

A user has reported success in resolving the issue by making a couple of modifications to the k-Wave code. Keep in mind that this is a workaround, and a more robust solution might be needed in future versions of k-Wave.

Step 1: Modify kspaceFirstOrder_inputChecking.m

  1. Open kspaceFirstOrder_inputChecking.m in the MATLAB editor.
  2. Locate the "Smooth and enlarge grids" section (around line 1488).
  3. Comment out or remove the lines that involve the smooth function. This prevents the grid from being smoothed, which seems to be the source of the incompatibility. You can comment out lines by adding a % at the beginning of the line.

For example:

    if flags.axisymmetric
        switch radial_symmetry
            case {'WSWA-FFT', 'WSWA'}

                % create a new kWave grid object with expanded radial grid
                kgrid_exp = kWaveGrid(kgrid.Nx, kgrid.dx, kgrid.Ny * 4, kgrid.dy);                 
                
                % mirror p0 in radial dimension using WSWA symmetry 
                p0_exp = zeros(kgrid_exp.Nx, kgrid_exp.Ny);
                p0_exp(:, kgrid.Ny*0 + 1:kgrid.Ny*1) =         source.p0;
                p0_exp(:, kgrid.Ny*1 + 2:kgrid.Ny*2) = -fliplr(source.p0(:, 2:end));
                p0_exp(:, kgrid.Ny*2 + 1:kgrid.Ny*3) =        -source.p0;
                p0_exp(:, kgrid.Ny*3 + 2:kgrid.Ny*4) =  fliplr(source.p0(:, 2:end));

            case {'WSWS-FFT', 'WSWS'}

                % create a new kWave grid object with expanded radial grid
                kgrid_exp = kWaveGrid(kgrid.Nx, kgrid.dx, kgrid.Ny * 2 - 2, kgrid.dy);                  
                
                % mirror p0 in radial dimension using WSWS symmetry 
                p0_exp = zeros(kgrid_exp.Nx, kgrid_exp.Ny);
                p0_exp(:,            1:kgrid.Ny)       =        source.p0;
                p0_exp(:, kgrid.Ny + 1:kgrid.Ny*2 - 2) = fliplr(source.p0(:, 2:end - 1));
                
        end

        % clean up unused variables
        clear kgrid_exp p0_exp;
    end

Step 2: Modify kspaceSecondOrder.m

  1. Open kspaceSecondOrder.m in the MATLAB editor.
  2. Go to the "Calculate FFT of source functions and expand grid" section (around line 328).
  3. Comment out or remove the lines that deal with grid expansion (the else block of the if ~expand_grid statement). This forces the code to use the original grid dimensions for the FFT calculations.
% =========================================================================
% CALCULATE FFT OF SOURCE FUNCTIONS AND EXPAND GRID
% =========================================================================

if ~expand_grid 
    
    % extract wavenumber matrix from kgrid
    k = kgrid.k;
    
    % extract the location of the sensor points
    sensor_index = (sensor.mask == 1);
    
    % compute FFT of source functions
    if source_case ~= 2
        p0_k = fftn(source.p0);
    end
    if source_case > 1
        dp0dt_k = fftn(source.dp0dt);
    end
    
else

Step 3: Run the Example

Now, try running the example_ivp_homogeneous_medium.m example again. The "incompatible size error" should be gone!

Important Considerations

  • This is a workaround: Modifying core k-Wave files isn't ideal. A proper fix should come from the k-Wave developers. Keep an eye on future releases for a more permanent solution.
  • Impact on Accuracy: Bypassing the grid smoothing and expansion might slightly affect the accuracy of your simulations, especially in axisymmetric cases. Be mindful of this when interpreting your results.
  • MATLAB Version: This issue seems to be more prevalent in MATLAB R2025b. Older versions might not exhibit the same behavior.

Reproducing the Error

To reproduce the error, simply run the example_ivp_homogeneous_medium.m example in MATLAB R2025b with a default installation of k-Wave (version 1.4).

System Information

  • Operating System: Windows
  • k-Wave Release Version: 1.4 (Default)
  • MATLAB Version: MATLAB R2025b

Wrapping Up

While this "incompatible size error" can be a real head-scratcher, this workaround should get you back on track with your k-Wave simulations. Remember to keep an eye out for official updates from the k-Wave team. Happy simulating, folks!