Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make values ​converge to the minimum value in a data series

Tags:

python

numpy

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

Example:

[[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

like image 983
Jred0n29 Avatar asked Oct 23 '25 08:10

Jred0n29


1 Answers

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]]

Linear Case

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]

Exponential Case

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]

Random Noise

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]

Generalization

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):

Comparison of the three decreasing functions.


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.

like image 195
Alexander L. Hayes Avatar answered Oct 25 '25 23:10

Alexander L. Hayes



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!