Hello,
I’m currently working on a project where I’m using UQPyLab to implement metamodels for a system characterized by a set of matrices.
System Description: The system is characterized by a 3x4 matrix A
, representing parameters that may or may not be modeled as uncertain parameters depending on the given combination.
Model Evaluation: I’ve developed a model function that accurately computes the system’s response (Yvals
) based on variations in A
.
Metamodel Implementation: Using Polynomial Chaos Expansion (PCE), I’m building a metamodel (myPCE
) to approximate the system’s behavior for faster computations and sensitivity analyses.
Issue Encountered: While the model evaluations (Yvals
) are computing correctly for each sample, the metamodel (myPCE
) seems to only capture variations in one specific matrix element ((0,0)
), despite correctly sampling variations in other elements (Xvals
). This discrepancy occurs specifically within the loop iterating over different combinations of parameters.
Outside Loop Behavior: Interestingly, outside of the loop, changing any of the matrix elements works fine, and the metamodel captures variations correctly. This observation suggests that the issue might be related to the loop or the way samples are processed within it.
I’m seeking insights or suggestions to understand why the metamodel behaves differently inside and outside the loop. Any alternative approaches or best practices for implementing metamodels in UQPyLab would be appreciated. Below, is a snippet of the loop that is causing issues.
Thank you in advance,
Eilidh
> indices_to_labels = {
> (0, 0): 'X_u', (0, 1): 'X_w', (0, 2): 'X_q', (0, 3): 'X_theta',
> (1, 0): 'Z_u', (1, 1): 'Z_w', (1, 2): 'Z_q', (1, 3): 'Z_theta',
> (2, 0): 'M_u', (2, 1): 'M_w', (2, 2): 'M_q', (2, 3): 'M_theta'
> }
>
> for idx, (combo, constants) in enumerate(ordered_combinations, start=1):
> print('-----------------')
> print('Combo:', combo)
> print('Constant derivatives:', constants)
>
> uq = create_session() # Reset session
>
> myModel = uq.createModel(ModelOpts)
>
> InputOpts = {'Marginals': []}
> all_indices = list(combo.keys()) + list(constants.keys())
>
> # Set up marginals based on the current combination and constants
> for index in all_indices:
> label = (index[0], index[1])
> value = A[index].item() # Convert numpy data type to Python native type
> dist_type = 'Gaussian' if index in combo else 'Constant'
> parameters = [value, float(abs(value * COV))] if dist_type == 'Gaussian' else [value]
>
> InputOpts['Marginals'].append({
> 'Name': str(label),
> 'Type': dist_type,
> 'Parameters': parameters
> })
>
> # Create input, get samples
> myInput = uq.createInput(InputOpts)
> Nval = 1
> samples = uq.getSample(myInput, Nval)
> Yvals = []
>
> ## Initialize the sampled matrices with original values of A for each sample set
> sampled_matrices = np.tile(A[:, :, np.newaxis], (1, 1, Nval))
>
> Xvals = []
> # Inject sampled values only for the varying parameters
> for param_idx, index in enumerate(all_indices):
> if index in combo:
> sampled_matrices[index[0], index[1], :] = samples[:, param_idx]
>
> print(f'Sampled Values for Combo {idx}:')
> for i in range(Nval):
> print(f'Sample {i+1}:')
> print(sampled_matrices[:, :, i])
> print('...........')
>
> # Evaluate the model for each sample
> sample_eval = uq.evalModel(myModel, sampled_matrices[:, :, i].flatten()) # Flatten if needed
> Yvals.append(sample_eval)
>
> # Append the sampled matrix to the list
> Xvals.append(sampled_matrices[:, :, i])
>
> print(Yvals)
> print(type(Yvals))
> print(np.shape(Yvals))
>
> # Define the metamodel options
> MetaOpts = {
> 'Type': 'Metamodel',
> 'MetaType': 'PCE',
> 'TruncOptions': {'qNorm': 0.75},
> 'Degree': np.arange(2, 11).tolist(),
> 'ExpDesign': {
> "NSamples": 120,
> "Sampling": "LHS"
> }
> }
>
> print('EXP DESIGN')
> print('CREATING METAMODEL')
> # print('samples for metamodel', Xvals)
> myPCE = uq.createModel(MetaOpts)
> print(myPCE)
>
>
> print('EVALUATING METAMODEL')
> # print('sampled matrices shape', Xvals.shape)
> print('Xvals for metamodel', Xvals)
> YPC = uq.evalModel(myPCE, Xvals)
> print('YPC', YPC)