Skip to content

Pre-stack modeling operator for multiple wavelets #648

@dprjoao

Description

@dprjoao

🛠 Multi-Wavelet Support in Pre-Stack Inversion Operator (explicit=False)

📖 Description

The convolution operator used by pylops for pre-stack inversion (explicit=False) is implemented using the Conv1D class. Currently, pylops supports only a single wavelet for all angles, meaning the inversion assumes the same wavelet for each angle.

I attempted to modify the code to allow a different wavelet for each angle (mid-angle in my case, as I’m using partial stacks). However, my current results are only consistent when using dense operators (explicit=True), whereas I would expect them to also work in the sparse case.


🔍 Observations

  • ✅ The dense implementation (explicit=True) behaves as expected.
  • ❌ The sparse implementation (explicit=False) does not produce comparable results.
  • ⚠️ The issue seems related to how the Conv1D operator is built when handling multiple wavelets.

The code using Conv1D for multiple wavelets is only working for spatdims=1 at the moment, the idea is to extend for 2D or 3D cases when i adress this issue.


💡 Code Snippet

Dense Implementation (Working)

# Handling multiple wavelets
if isinstance(wav, list):
    print("Dense multi-wavelet operator")
    n = len(wav)
    C = np.zeros((n * nt0, n * nt0))

    wsub_list = []
    for w in wav:
        wsub = np.asarray(convmtx(w, nt0, len(w) // 2)[:nt0])
        wsub_list.append(wsub)

    C = get_block_diag(theta)(*wsub_list)

else:
    # Create wavelet operator
    C = ncp.asarray(convmtx(wav, nt0, len(wav) // 2)[:nt0])
    C = [C] * ntheta
    C = get_block_diag(theta)(*C)

# Combine operators
M = ncp.dot(C, ncp.dot(G, D))
Preop = MatrixMult(M, otherdims=spatdims, dtype=dtype)

Sparse implementation (Not-working)

    else:
        if isinstance(wav, list):
            print("Dense multi-wavelet operator")
            # Criar uma lista de operadores de convolução
            Cop_list = []

            for w in wav:
                Cop = Convolve1D(
                    (nt0),
                    h=w,
                    offset=len(w) // 2,  # Define o centro da wavelet
                    axis=0,
                    dtype='float32',
                    method='fft'
                )
                Cop_list.append(Cop.tosparse())  # Adiciona à lista de operadores'
            

            Cop = BlockDiag(Cop_list)

        else:
            print("Sparse single wavelet operator")
            # Create wavelet operator
            Cop = Convolve1D(
                dims,
                h=wav,
                offset=len(wav) // 2,
                axis=0,
                dtype=dtype,
            )

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions