I'm writing a code and I have a function that calculates the values that are not fulfilling a condition with the values that are fulfilling the condition, but I'm having a lot of trouble with managing the shape of the arrays.
I have a similar function, but with other logical structure that does this (MWE for the function that works)
import numpy as np
def f_est(f, fd, mask):
"""
This function returns the estimated value given a function f and its derivative fd
for the points selected by the mask, estimating forward.
Parameters:
- f: Array of function values.
- fd: Array of derivative values of the function.
- mask: Boolean mask to select points in f and fd.
"""
h = 0.000001
# Find the last index that satisfies the mask
last_index = np.max(np.where(mask)[0])
# Create shifted masks (inspired by f_cal), but centered on the last index
mask_current = mask[:last_index + 1] # Mask for current positions up to the last index
mask_prev = mask[:last_index] # Mask for previous positions (for fd_prev_slice)
mask_prev2 = mask[:last_index - 1] # Mask for previous positions (for fd_prev2_slice)
# Apply masks to f and fd (with shifts), centered on the last index
f_slice = f[:last_index + 1][mask_current] # Note: adjusted to align with mask_current
fd_slice = fd[:last_index + 1][mask_current]
fd_prev_slice = fd[:last_index][mask_prev]
fd_prev2_slice = fd[:last_index - 1][mask_prev2]
# Perform the calculations with consistent slices, estimating forward
# Use the last value of f_slice, fd_slice, fd_prev_slice, and fd_prev2_slice for estimation
last_f = f_slice[-1]
last_fd = fd_slice[-1]
last_fd_prev = fd_prev_slice[-1] if len(fd_prev_slice) > 0 else 0
last_fd_prev2 = fd_prev2_slice[-1] if len(fd_prev2_slice) > 0 else 0
estimated_next_value = (
last_f
+ h * last_fd
+ 1 / 2 * (h * last_fd - h * last_fd_prev)
+ 5 / 12 * ((h * last_fd - h * last_fd_prev) - (h * last_fd_prev - h * last_fd_prev2))
)
return estimated_next_value
f = np.array([1, 2, 3, 4, 5, 6, 7])
fd = f
mask = np.array([True, True, True, False, False, False, False])
print("Original Array:", f)
print("Length of Original Array:", len(f))
print("Masked Array:", f[~mask])
print("Length of Masked Array:", len(f[~mask]))
f[~mask] = f_est(f, fd, mask)
print("Final Array:", f)
print("Length of Final Array:", len(f))
But with this function (MWE that doesn't work):
import numpy as np
def f_cal(var, dvar, mask):
"""
Calculates next value using trapezoidal method with masks, estimating forward.
Parameters:
var: array of current values
dvar: array of derivatives
mask: boolean array indicating which positions to calculate
"""
h = 0.0000001
# Encontrar el último índice que verifica la máscara
last_index = np.max(np.where(mask)[0])
# Crear máscaras para posiciones actuales y la siguiente
mask_current = mask[:last_index]
mask_next = mask[1:last_index+1] # Marcar como True el índice siguiente
# Ajustar los arreglos para alinear con las máscaras
var_current = var[:last_index+1][mask_current]
dvar_current = dvar[:last_index+1][mask_current]
dvar_next = dvar[:last_index+2][mask_next][:1] # Solo el valor siguiente
# Calculate using trapezoidal method with masks, estimating forward
result = var_current + h * dvar_next - 1/2*(h*dvar_next-h*dvar_current[-1])
return result
f = np.array([1, 2, 3, 4, 5,6,7])
fd = f
mask = np.array([True, True, True, False, False, False, False])
print("Original Array:", f)
print("Length of Original Array:", len(f))
print("Masked Array:", f[~mask])
print("Length of Masked Array:", len(f[~mask]))
f[~mask] = f_cal(f, fd, mask)
print("Final Array:", f)
print("Length of Final Array:", len(f))
I'm having a lot of trouble keeping the length of the array to match the number of elements that are not satisfying the condition
dvar_currentanddvar_next? Shouldresultbe an array, or should it be a number as in the working example; if an array what size depending onlen(f[mask])? I also don't get the working example, the waylast_fd_prev2is computed doesn't seem consistent. There,last_fis alwaysf[mask][-1],last_fdis alwaysfd[mask][-1],last_fd_previs alwaysfd[mask][-2] if len(fd[mask]) > 1 else 0whilelast_fd_prev2appears to be a mistaken way to computefd[mask][-3] if len(fd[mask]) > 2 else 0.