From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Scaling an Array of Numbers

Solved!
Go to solution

Hello! 

So I have a 2D array of values from 0 to 1023 that represent readings from a sensor. I need to scale these to -200 to 200. Any ideas on how to easily do this? Thanks!

 

Example of array:

 

514  578  233

513  555  122

513  789  514

0 Kudos
Message 1 of 16
(3,729 Views)

Math.

 

Take array, divide by 1024, multiply by 401.  Subtract 200.

 

 

Message 2 of 16
(3,723 Views)
Solution
Accepted by topic author ebohannon

@RavensFan wrote:

Math.

 

Take array, divide by 1024, multiply by 401.  Subtract 200.


Doesn't that scale between -200 and 200.608 (1023/1024*401-200=200.608)?

 

AFAIC, divide by 1023, multiply by 400, subtract 200.

 

Or, more general subtract the min input, divide between max input - min input, multiply by output range, add output offset.

 

And of course if the array gets big, divide 400 by 1023 first, then multiply it by the array. That will trait two expensive array multiplications for one scalar multiplication and one array multiplication.

Message 3 of 16
(3,675 Views)

wiebe@CARYA wrote:

@RavensFan wrote:

Math.

 

Take array, divide by 1024, multiply by 401.  Subtract 200.


Doesn't that scale between -200 and 200.608 (1023/1024*401-200=200.608)?

 

AFAIC, divide by 1023, multiply by 400, subtract 200.

 

Or, more general subtract the min input, divide between max input - min input, multiply by output range, add output offset.

 

And of course if the array gets big, divide 400 by 1023 first, then multiply it by the array. That will trait two expensive array multiplications for one scalar multiplication and one array multiplication.


Hard to say.   0-1023 consists of 1024 integer values.

-200 to 200 consists of  401 integer values  +/- 1-200  and zero in the middle.

 

The answer should get the OP close enough.  If it doesn't quite work the way they want, then perhaps they need 400 instead of 401.  Or 1023 instead of 1024.  Or perhaps both.  The two ranges aren't easily divisible with each other.  So answer may never be exact.

 

0 Kudos
Message 4 of 16
(3,669 Views)

wiebe@CARYA wrote:

And of course if the array gets big, divide 400 by 1023 first, then multiply it by the array. That will trait two expensive array multiplications for one scalar multiplication and one array multiplication.


Do you know if compound arithmetic is smart enough to do this internally?

0 Kudos
Message 5 of 16
(3,662 Views)

@Alexander_Sobolev wrote:

wiebe@CARYA wrote:

And of course if the array gets big, divide 400 by 1023 first, then multiply it by the array. That will trait two expensive array multiplications for one scalar multiplication and one array multiplication.


Do you know if compound arithmetic is smart enough to do this internally?


Not without testing.

 

It would be silly if it didn't, so my bet would be that it is smart enough.

Message 6 of 16
(3,656 Views)

Another option would be to use linear evaluation (offset and slope have been discussed).

 

Also works for 2D arrays, of course.

 

lineval.png

0 Kudos
Message 7 of 16
(3,639 Views)

wiebe@CARYA wrote:

@Alexander_Sobolev wrote:

wiebe@CARYA wrote:

And of course if the array gets big, divide 400 by 1023 first, then multiply it by the array. That will trait two expensive array multiplications for one scalar multiplication and one array multiplication.


Do you know if compound arithmetic is smart enough to do this internally?


Not without testing.

 

It would be silly if it didn't, so my bet would be that it is smart enough.


Seems that I was wrong...

 

Here's my test bench. And it's tricky, Sometimes any change makes the time double, and a random change makes it go back. I feel like these values are "realistic" though, after giving each option several go's. I used a median before the mean, as strong outliers added about 20% noise on the results.

Bench test compound arithmetic.png

 

The results:

Bench test compound arithmetic results.png

Definitely some unexpected weirdness going on here!

 

A being (much) faster then B? Weird!

A being (much) faster then C? Weird!

B being faster then C? Weird!

E being the slowest? Sad. A factor 2.3 is quite a bit slower... This could\should be just as fast as A.

 

DISCLAMER: Tested in 2013... 2017SP1 is a bit faster for all cases, but the order and ratios are pretty much the same.

 

EDIT: It get worse:

Bench test compound arithmetic results Extra.png

5.5 times slower then the fastest way... Smiley Sad

 

And, just for the record:

Bench test compound arithmetic results Extra2.png

0 Kudos
Message 8 of 16
(3,606 Views)

wiebe@CARYA wrote:

B being faster then C? Weird!


They are within the noise.  I would expect them to actually compile to the same thing due to optimizations that the compiler does such as moving that first multiply outside of the loop.


GCentral
There are only two ways to tell somebody thanks: Kudos and Marked Solutions
Unofficial Forum Rules and Guidelines
"Not that we are sufficient in ourselves to claim anything as coming from us, but our sufficiency is from God" - 2 Corinthians 3:5
0 Kudos
Message 9 of 16
(3,596 Views)

That it's slower when you wire the scalars on top isn't that surprising. There's some threads on LV memory management, and if you wire an array on top it usually work in place, while a scalar on top forces it to create a new array.

/Y

G# - Award winning reference based OOP for LV, for free! - Qestit VIPM GitHub

Qestit Systems
Certified-LabVIEW-Developer
0 Kudos
Message 10 of 16
(3,590 Views)