05-05-2022 04:30 PM - edited 05-05-2022 04:37 PM
I would like to be able to generate a logarithmic array of numbers with a user entered start, end, and number of points (array entries) to create. I can do a linear version pretty easily, but can't crack how to do this logarithmically.
IE user wants to start at 1,000, end at 100,000 with 3 points, the entries 1,000, 10,000, and 100,000 would be generated for logarithmic, and 1,000, 50,500, and 100,000 for linear.
(Edit - the absolute value function should probably not be there, but assume I do some checking to make sure end freq. is higher than start freq.)
(vi saved for LV2017)
Solved! Go to Solution.
05-05-2022 05:26 PM - edited 05-05-2022 05:48 PM
This turns out to be more of an algebra problem than a programming problem. I'll assume natural logs to keep the notation simple.
You've already got a method for the linear version and you'll use it for the logarithmic version.
Just apply the linear-spacing function to the new endpoints ln(start), ln(end), along with the # of array values you want. So then you have an array of {natural logs of values} which increases linearly. Now take that array and do exp(array) to transform back to values in the original range where they'll increase logarithmically.
-Kevin P
[Edit: P.S. Just found myself with a few minutes to adapt your code enough to illustrate]
05-05-2022 06:04 PM
Thank you very much. If you will bear (bare?) with me a minute, I have sufficiently foregotton enough algebra, but I believe the logic behind this for logarithmic interpolation:
Get the natural log of the start and end, get the difference and add that to the start n-1 times, then raise e to the power of the natural log of the starting number + the difference between the natural log of the starting freq and the ending freq.
Seems to make sense to me, but correct me if I am wrong.
05-05-2022 08:35 PM
Yep, that's it. The whole middle section between the 2 case structures is just your algorithm for linear spacing. I only did a little minor rearranging and wire straightening.
The idea is to transform into log space, solve the linear spacing problem *there*, and then transform back to normal space.
Let's do an example with base-10 logs for simplicity of illustration:
Let's set the start at 10, the end at 100000, and ask for 5 total points.
Transform to log space -> start at 1, end at 5 with 5 total points.
Those points are simply 1,2,3,4,5, representing log10 of the values you want in normal space.
So you apply 10^x on them and get 10,100,1000,10000,100000.
Note: the idea works the same way regardless of whether you use base-10 logs and 10^x or base-e natural logs and exp(x).
-Kevin P
05-05-2022 08:49 PM
05-05-2022 08:55 PM - edited 05-05-2022 09:00 PM
@StevenD wrote:
IE user wants to start at 1,000, end at 100,000 with 3 points, the entries 1,000, 10,000, and 100,000 would be generated for logarithmic, and 1,000, 50,500, and 100,000 for linear.
Good enough? Once you make the type a control, the type (lin or log) can be selected by the user.
05-05-2022 10:28 PM
I feel like Altenbach would be a billionaire if they were a miner with all the hidden gems they can find 😂
On a more serious note, kind of disappointed that under the hood is just a dll. I would love to see the code going on in there.
05-05-2022 10:30 PM
Note: the idea works the same way regardless of whether you use base-10 logs and 10^x or base-e natural logs and exp(x).
I did notice that, could to log base 10, then 10^x. It was fun figuring out what you did!
05-06-2022 12:32 AM - edited 05-06-2022 12:35 AM
Without the ramp pattern, I would probably do something like the following:
I definitely would not use the min&max (as Kevin did above), because sometimes we want a descending ramp, i.e. the first array element should be the largest. There is nothing wrong having start>end and the stock ramp pattern does it right.
Also these incremental adds in the shift register might accumulate more rounding errors in the long run (i.e. for very large N)
05-06-2022 07:24 AM
As per usual, it pays to listen to altenbach.
1. I didn't realize the Ramp Pattern function had the logarithmic spacing option! That's clearly the simplest solution, and prevents subtle bugs you may introduce by rolling your own algorithm.
2. He's right to point out the possible issue with roundoff caused by successive summing. My spidey senses tingled a little at that part too, but I left it that way on purpose so my illustration would re-use the algorithm you'd already done -- so it'd be easier to see that the only difference is the transforms via ln() and exp(). Still, it's all a moot point when Ramp Pattern can do it for you directly.
3. I agree that the Min & Max definitely wouldn't belong for the general case. It was specifically to address the OP's concern about making sure that end >= start. It's one possible approach but not always the most appropriate one. Some situations would be better served by producing some kind of error and/or null output rather than just swapping start & end. Others are fine with the swap. As is often the case, "it depends."
Again, bottom line: listen to altenbach.
-Kevin P