Jump to content

Recommended Posts

What I am trying to do probably makes no sense, and I really have no idea what i'm doing in this place of algebra but here is my problem ...

I am trying to populate a list of values from min (x) to max (y) increasing the values by the step amount (z) easy enough, but I want to have the step value increase in size as the numbers get larger and larger so I don't have  a list the size 'max / step', if max is say 5000000.
So once the current value reaches another place the step value matches in increase by the same amount: min(0); max(5000000); starting step(2500);

                                + 2500                       +25000                                                                                         +250000
Expected output: [0, 2500, 5000, 7500, 10000, 25000, 50000, 75000, 100000, 125000, ... , 975000, 1000000, 1250000, ... ]

Below is probably just a bunch of junk, so maybe cover your eyes from this part, as It likely will lead you no where but I would not really know ...

// Limits
_min_value = 0;
_max_value = 5000000;

// Init
_values = [];
_current_value = _min_value;

// Init loop variables
_value_step = 2500;
_step_power = floor(log _value_step);
_base_step = _value_step / (10 ^ _step_power);

// Populate values
while {_current_value <= _max_value} do {
	
  // Push to value list
  _values pushBack _current_value;
  
  // Figure step amount
  _current_value_power = floor(log _current_value);
  _value_step = _base_step * (10 ^ _current_value_power);
  _powers_difference = _current_value_power - _step_power;

  // ...
	
  // Update current value
  _current_value = _current_value + _value_step;
};

 

I figured this fell into the category of logarithms but I am apparently not very good at learning and using them as I have been stuck on trying to complete this problem all day. Please help 🙂

 

Note: I would like to figure this problem without a bunch of 'if' or 'switch' statements, just good old reliable math

Share this post


Link to post
Share on other sites

Is this just Math for Math or do you have something more consistent to do with?

Share this post


Link to post
Share on other sites

Had to read the first post at least 5 times and still don't quite get it.

The example also doesn't make sense since 10000+25000 != 25000.

Do you want to increase the step size after a certain value has been reached?

Could be like this:

_output = [];
_max = 500000;
_steps = [2500,25000,250000];
_increaseAt = [0,10000,100000];
_current = 0;
_increase = 0;
while {_current < _max} do {
	if (_increaseAT find _current > -1) then {_increase = _steps#(_increaseAt find _current)};
	_current = _current + _increase;
	_output pushBack _current;
};
hintSilent str _output;
copyToClipboard str _output;
  
//prints:
[2500,5000,7500,10000,35000,60000,85000,110000,135000,160000,185000,210000,235000,260000,285000,310000,335000,360000,385000,410000,435000,460000,485000,510000]

Cheers

  • Like 2

Share this post


Link to post
Share on other sites

So the inputs are Min and Max. Say the "steps" move us along the X-axis, and on the Y-axis we have the value. Using just a linear function where the Y value is the element position in the output: "Y = StepSize * X + Min" where X is the same as Index in this case, it might take a long time (many Index) to reach Y >= Max as you already observed.

 

So rather than that, let us use a polynomial (second-degree) and drop the step size for now and just consider this perhaps: "Y = X^1.8" (this looks like this, https://www.wolframalpha.com/input/?i=y+%3D+x^1.8+where+0+<+x+<%3D+1 ). The thing we are looking for here is whether the "curve" itself looks right. The normal linear is "Y = X^1". This one makes it rise much slower in the start and much faster in the end; notice the midpoint for X=0.5 is only about Y=0.3. So half of the values would be in the first 30%. By increasing, e.g. to ^3, half would be in lower 10% of the value.

To use this we just need to map our index to 0-1 and map the output to the proper value. So how many values? Well you can easily pick that yourself:

NNJ_fnc_Populate = {
    params ["_min", "_max", "_count", ["_pow", 1.8]];
    private _result = [];
    // We iterate from 0 to count-1 and need to divide by count-1 anyway
    private _countMinusOne = _count - 1;
    private _maxMinDiff = _max - _min;
    for "_i" from 0 to _countMinusOne do {
        // Normalize the X value to between 0 and 1 (inclusive)
        private _xVal = _i / _countMinusOne;
        // Compute the normalized Y-value
        private _yVal = _xVal ^ _pow;
        // Map the _yVal back to the desired range
        private _value = _min + _maxMinDiff * _yVal;
        _result pushBack _value;
    };
    _result
};

// So if you want a 1000 values.
private _min = 0;
private _max = 5000000;
private _valuesA = [_min, _max, 1000] call NNJ_fnc_Populate;
// Or you want 3000 values distributed but rounded, and using ^1.2
// Note, if you round with a power too multiple elements in the beginning may be the same, e.g. zeroes and ones.
private _valuesB = ([_min, _max, 1000, 1.2] call NNJ_fnc_Populate) apply {round _x};

 

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×