How can i generate an array of integers that is more dense around a certain value?

Hi all, I hope that someone could help me. I need to generate a vector of positive integers in a certain range (let say 1 and 100) linearly spaced that is more dense (aka has more points) around a certain value (let say 60).
EDIT: I need this vector as a range for a for loop. Thus it must not include any repetitions.
I tried to code like this but the following code is not very efficient neither robust to changes in the parameter choice:
M = 10000;
ending_point = 0.01*M;
density_sample = 5;
starting_point = 1;
num_roots_gin = 60;
quantity1 = round(0.5*num_roots_gin);
array = [starting_point:density_sample:ending_point];
tol = 3; %must be less than density
[ff,gg] = find(abs(vettore-num_roots_gin)<tol);
array2 = [(num_roots_gin-quantity1):(num_roots_gin+quantity1)];
array_fin = [array(1:ff-1) array2 array(ff+1:end)];

8 Comments

Why not something like,
x=min(max(poissrnd(30,1e6,1),1),100);
histogram(x,100); xlim([1,100])
my apologies, I was not enough clear in my explanation: I need this vector as a range for a for loop. Thus it must not include any repetitions.
Highly confusing. You want a vector that is linearly spaced, BUT is denser in some places than in others???? As much as I want to offer a solution, that makes little sense. Entirely integer, and you know how many elements you want to produce? No matter what you do, this will fail, SOME of the time.
I'm confused, too.
Could you give a few examples of vectors that are linearly spaced integers in the range 1:20 and are more dense around 5?
Do you mean something like
  • [2,3,4,5,6]
  • [3,4,5,6,7]
  • [4,5,6,7,8]
would occur more frequently than
  • [12,13,14,15,16]
  • [13,14,15,16,17]
  • [14,15,16,17,18]
?
I am sorry if I did not manage to be clear. I would meant that in the neighbourhood of a certano value, say 5, we have more points(equally spaced, e.g. spaced by unitary Interval) and far from this value are linearly spaced but with an interval larger than 1 (Maybe 3 or something like this). This is what I tried to code in my example, to generete two vectors and then concatenate them coherently, but if there is another way to do this I am really pleased to try. Sorry again for the misunderstanding, hope that now is a little bit clearer
You've stated what you're hoping the code will do. But let's take a step back. Can you explain (in words not in code) what problem you're trying to solve with this integer valued array? What about the problem you're trying to solve requires that array to be more dense in some areas (and so less in others)? I can think of a couple potential reasons, but I'd like to hear what you have in mind.
Of course i will explain! Given the standard structure of the for loop in MATLAB
for index = values
statements
end
this integer valued array will be used as "values" thus it must be an increment index by the value step on each iteration.
I need this vector to be more dense around a specific value because this for loop solves a very long optimization problem so I need to solve it with a smaller step only in a neighborhood of a certain value that I know that it is a threshold for seeing an interesting phenomena. On the other hans, the other points far from this specific value or threshold, are still important but can be analyzed by means of a bigger step as I do not expect any macroscopic differences in the solutions of the optimization problem for that values. I hope it is more clear now.
So are you calling your optimizer multiple times, first to identify the broad region where your solution lies then later to localize the solution even further? Like using your optimizer to find what state contains the answer, then using it again to find which city in that state has the answer, then what neighborhood in the city, then what street in the neighborhood, etc.?
It's still not completely clear to me over what you're iterating and why those need to be integer values. If what I described in the first paragraph of my comment is close I'd call the optimizer once with a very coarse set of tolerances (say an absolute tolerance of 1) then call it over and over again, using the final result from the previous optimizer call as the initial guess for the next optimizer call with progressively smaller tolerances (switching to an absolute tolerance of 1e-2, then 1e-4, then 1e-8, etc.)

Sign in to comment.

 Accepted Answer

The example you gave doesn't seem to do what you describe. Is this more what you're looking for?
M = 10000;
ending_point = 0.01*M;
starting_point = 1;
density_sample = 5;
num_roots_gin = 60;
% half-width of high-density window
% this is the number of low-density samples on each side of the point of interest (>=1)
halfw = 2;
array = starting_point:density_sample:ending_point; % low-density linear series
[~,gg] = min(abs(array-num_roots_gin)); % find the index of the element closest to target
array2 = array(gg-halfw):array(gg+halfw); % max density linear segment between adjacent elements
array_fin = [array(1:gg-1-halfw) array2 array(gg+1+halfw:end)]
array_fin = 1×36
1 6 11 16 21 26 31 36 41 46 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
plot(array_fin,'.-'); hold on
yline(num_roots_gin)
This doesn't ensure that the high-density segment is exactly centered on the point of interest, but it's not clear that it's necessary. Also, I haven't done anything to safeguard against the window hanging off the end of the low-density series (causing an indexing error).

1 Comment

yes, this definetly is closer to the desidered behavior that I was looking for. Thanks

Sign in to comment.

More Answers (1)

Honestly, you could probably do something using an optimization. But using an optimization technique to solve this seems to be the equivalent of using a Mack truck to carry a pea to Boston - wild overkill. I'd formulate an objective function that would push the vector to have as uniform a spacing as possible, but also would "encourage" more points near the target, while also forcing the solution to be entirely integer. UGH. In fact, UGH squared. It just seems like an ugly way to generate a vector that has the properties you want.

Categories

Products

Release

R2021b

Asked:

on 27 Jun 2023

Commented:

on 27 Jun 2023

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!