I have the following code to generate an array:
import numpy as np
dimension = 2
tamaño = 8
decrement = 0.9
matriz = np.asarray([np.random.random(dimension) for _ in range(tamaño)])
print(matriz)
minimo = np.amin(matriz[:,0])
for _ in range(100):
#Es aqui donde graduaremos exponencialmente los valores
I have a matrix of size 2x8. I then identify the minimum value in the column "[0]", in order to create a loop of N iterations to make that in each of them the other elements converge to that minimum value But The issue is that for them to converge in a "gradual" way, the value of the decrease variable would not have to be the same for everyone and that is where my question comes from. What would I have to do to modify the value of the variable in each iteration " Decrement"" To such an extent that when the last iterations are reached there is a minimum standard deviation
Psdt: I found this on SO I hope it helps
numpy / scipy: Making one series converge towards another after a period of time
[[0.90853515 0.62336012]
[0.01582124 0.92943723]
[0.69089692 0.99732285]
[0.17234051 0.13713575]
[0.93259546 0.69681816]
[0.06600017 0.75546305]
[0.75387619 0.92302454]
[0.71152476 0.12427096]]
As we can observe the minimum value of that matrix would be:
0.015821242846556283
What we have to proceed to do is auto-adjust the other values in each iteration minimally as long as they converge to the minimum at the end of the column in which we are adjusting. It could look like this:
[0.01592127
0.01589542
0.015826342
0.01534542
0.01582452
0.015834542
0.0158456
0.01582435]
Nota: They don't have to perfectly converge after their first 2 or 3 digits are the same, the others don't matter so much I accept several solutions to this problem They don't have to perfectly converge after their first 2 or 3 digits are the same, the others don't matter so much I accept several solutions to this issue
Let's rewrite some of this for reproducibility:
import numpy as np
from numpy.random import default_rng
rng = default_rng(3)
matriz = rng.random((8, 2))
minimo = np.min(matriz[:,0])
Here the matriz will look like the following, and minimo will be bound to 0.08564916714362436:
[[0.08564917 0.23681051]
[0.80127447 0.58216204]
[0.09412864 0.43312694]
[0.4790513 0.15973891]
[0.73457715 0.11367202]
[0.39122819 0.51674018]
[0.43062802 0.58679857]
[0.73783779 0.95626725]]
If the goal is to find an array where the final value decreases until the minimo value, the simplest solution might be:
SCALE = 0.001
sequence = (np.arange(matriz.shape[0])[::-1] * SCALE) + minimo
which results in:
[0.09264917 0.09164917 0.09064917 0.08964917 0.08864917 0.08764917
0.08664917 0.08564917]
If the goal is instead to decrease the values such that they follow an exponential, another parameter can be added:
LIN_SCALE = 0.1
EXP_SCALE = 2.0
sequence = ((np.arange(matriz.shape[0])[::-1] * LIN_SCALE) ** EXP_SCALE) + minimo
Which results in:
[0.57564917 0.44564917 0.33564917 0.24564917 0.17564917 0.12564917
0.09564917 0.08564917]
One final point mentioned in the question is the presence of noise: such that it may not matter exactly how much the sequence decreases by, so long as the final number converges to the minimum value.
We could represent this by sampling from a normal distribution with loc=0.0, scale=SIG_SCALE:
LIN_SCALE = 0.1
EXP_SCALE = 2.0
SIG_SCALE = 0.1
noise = rng.normal(scale=SIG_SCALE, size=matriz.shape[0])
noise[-1] = 0.0
ran_seq = (
((np.arange(matriz.shape[0])[::-1] * LIN_SCALE) ** EXP_SCALE) + noise
) + minimo
Which looks something like this:
[0.62384371 0.42179381 0.43142504 0.22566895 0.17807512 0.28023125
0.15015972 0.08564917]
The final version can be generalized. For example: the linear decreasing case is produced when the exponential parameter is 1.0 and the random scale parameter is 0.0: which corresponds to raising the vector to the first power (no effect) and sampling from a 0-variance distribution (no effect):

Further Explanation: The idea here is to guarantee convergence by linearly decreasing in each step. Reversing the result of np.arange gives an array that decreases from 7 down to 0. Multiplying this by our SCALE parameter simply makes these values smaller. Finally, adding the minimo value to this array makes it so every rescaled value is proportional to the smallest value (and since the final value from the arange call is 0, 0 + minimo = minimo).
1. [7 6 5 4 3 2 1 0] # np.arange(8)[::-1]
2. [0.007 0.006 0.005 0.004 0.003 0.002 0.001 0. ]
3. [0.092 0.091 ... 0.0856]
This should guarantee a strictly monotonic decreasing sequence, and only requires setting the LIN_SCALE or EXP_SCALE parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With