Find successive maximum differences in array - ios

I have created an application in which the user continually rotates the phone about the z-axis (yaw) with the screen of the phone facing upwards. I would like to generate the angle between the two extremes each time the rotation changes direction.
Imagine an array of the following values: [-5,-3,-2, 0, 1, 2, 6, 5, 3, 2,-1,-3,-4,-7,-4,-3,...]. What I would like to do is find the relative maximums and minimums of the array in order to find the differences from one relative minimum to the next relative maximum. In the given array, -5 would be the first relative minimum and then 6 would be the next relative maximum. The difference here would be 11 units. From that relative maximum of 6, the next relative minimum is -7. The difference here would be 13 units. The process would continue on until the end of the array. I would like these difference values to be entered into an array of their own, i.e. [11,13,...]. Would greatly appreciate any assistance!

The way I see this your first value in the array is always your initial relative minimum AND maximum since you have absolutely no basis of comparison from the get-go (unless you prime both relMin and relMax to 0 OR define a range to find your relMin and relMax). With that in mind the logic behind your example itself is flawed given your assumption of using -5 & 6 as the first comparison pair.
Let's use your array and iterate through the array with a For Loop...
[-5,-3,-2, 0, 1, 2, 6, 5, 3, 2,-1,-3,-4,-7,-4,-3,...]
0: relMin = -5, relMax = -5, delta = 0
1: relMin = -5, relMax = -3, delta = 2
2: relMin = -5, relMax = -2, delta = 3
3: relMin = -5, relMax = 0, delta = 5
4: relMin = -5, relMax = 1, delta = 6
5: relMin = -5, relMax = 2, delta = 2
6: relMin = -5, relMax = 6, delta = 11
7:
....
13: relMin = -7, relMax = 6, delta = 13
....
Essentially what you're doing is writing to your output array any time your current delta is not equal to your previous delta. Since a change between relMin and relMax is mutually exclusive (only one of those values can change as you traverse the array) all you have to check for is inequality...
//prime your values
//if it make sense for your purposes prime them both with 0
//this also assumes you have at least 1 value in valueArray
relMin = valueArray[0];
relMax = valueArray[0];
//the following line will always be true if you use valueArray[0] as your relMin and relMax baseline
deltaArray[0] = 0;
for (i = 0; i < [valueArray count]; i++)
{
if (valueArray[i] < relMin)
{
relMin = valueArray[i];
}
if (valueArray[i] > relMax)
{
relMax = valueArray[i];
}
deltaPrevious = deltaArray[[deltaArray count] - 1];
deltaCurrent = relMax - relMin;
if (deltaCurrent != deltaPrevious)
{
deltaArray[deltaArray count] = deltaCurrent;
}
}

My approach to this problem would be to first write an algorithm that detects the indices of the maximums and minimums, and then finds differences from there.
To get the maxes and mins, I would recommend iterating through the array and looking at the difference between the current and the previous and next value. You need to looking at changes in sign of the differences:
A minimum will occur when the differences change from negative to positive, and a maximum will occur when the differences change from positive to negative.
For example, look at this part of your array: [1,2,6,5,3]. The difference from 1 to 2 is positive, from 2 to 6 is positive, but from 6 to 5 is negative. The sign of the differences changed from positive to negative at the 6, so we know it is a maximum.
Note that you also need to include the first and last elements as possible maxes or mins.
Once you get the indices of maximums and minimums, you should be able to get their differences fairly easily.

In a most basic sense, you could iterate through the array, checking to see if the next value is greater than or less than the previous value. Whenever you reach a change (was increasing, now decreasing, or vice versa) you have found a relative max/min (respectively). A for loop to iterate, a boolean flag to check against (whether you were increasing or decreasing) and the obvious knowledge of both your current and previous index in the array to check/store.
I don't quite feel comfortable giving exact code for this since it's very basic and seems very much like a homework question...

Related

Algorithm to always sum sliders to 100% failing due to zeroes

This is (supposed to be) a function which makes sure that the the sum of a number of slider's values always adds up to globalTotal.
A slider value can be changed manually by the user to changer.value and then when applying this function to the values of the other sliders, it can determine their new or endVal.
It takes the startVal of the slider which needs changing and the original value of the slider that changed changerStartVal and can determine the new value others by weighting.
The problem and my question is. Sometimes remainingStartVals can be zero (when the slider changing gets moved all the way to maximum) or startVal can be zero (when the slider changing is moved to zero and then another slider is moved). When this happens I get a divide-by-zero or a multiply-by-zero respectively. Both of which are bad and lead to incorrect results. Is there an easy way to fix this?
func calcNewVal(startVal: Float, changerStartVal: Float) -> Float {
let remainingStartVals = globalTotal - changerStartVal
let remainingNewVals = globalTotal - changer.value
let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
return endVal
}
This is a mathematical problem, not a problem related to Swift or any specific programming language so I'll answer with mathematical formulas and explanations rather than code snippets.
I don't really understand your algorithm either. For example in this line:
let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
you first multiply by 100 and then divide by 100, so you could just leave all these 100 factors out in the first place!
However, I think I understand what you're trying to achieve and the problem is that there is no generic solution. Before writing an algorithm you have to define exactly how you want it to behave, including all edge cases.
Let's define:
vi as the value of the i-th slider and
Δi as the change of the i-th slider's value
Then you have to think of the following cases:
Case 1:
0 < vi ≤ 1 for all sliders (other than the one you changed)
This is probably the common case you were thinking about. In this case you want to adjust the values of your unchanged sliders so that their total change is equal to the change Δchanged of the slider you changed. In other words:
∑i Δi = 0
If you have 3 sliders this reduces to:
Δ1 + Δ2 + Δ3 = 0
And if the slider that changed is the one with i = 1 then this requirement would read:
Δ1 = – (Δ2 + Δ3)
You want the sliders to adjust proportionally which means that this change Δ1 should not be distributed equally on the other sliders but depending on their current value:
Δ2 = – w2 * Δ1
Δ3 = – w3 * Δ1
The normed weight factors are
w2 = v2 / (v2 + v3)
w3 = v3 / (v2 + v3)
Thus we get:
Δ2 = – v2 / (v2 + v3) * Δ1
Δ3 = – v3 / (v2 + v3) * Δ1
So these are the formulas to applied for this particular case.
However, there are quite a few other cases that don't work with this approach:
Case 2:
vi = 0 for at least one, but not all of the sliders (other than the one you changed)
In this case the approach from case 1 would still work (plus it would be the logical thing to do). However, a slider's value would never change if it's zero. All of the change will be distributed over the sliders with a value > 0.
Case 3:
vi = 0 for all sliders (other than the one you changed)
In this case the proportional change doesn't work because there is simply no information how to distribute the change over the sliders. They're all zero! This is actually your zero division problem: In the case where we have 3 sliders and the slider 1 changes we'll get
v2 + v3 = 0
This is only another manifestation of the fact that the weight factors wi are simply undefined. Thus, you'll have to manually define what will happen in this case.
The most plausible thing to do in this case is to distribute the change evenly over all sliders:
Δi = – (1 / n) * Δ1
where n is the number of sliders (excluding the one that was changed!). With this logic, every slider gets "the same share" of the change.
Now that we're clear with our algorithm you can implement these cases in code. Here some pseudo code as an example:
if sum(valuesOfAllSlidersOtherThanTheSliderThatChanged) == 0 {
for allUnchangedSliders {
// distribute change evenly over the sliders
Δi = – (1 / n) * Δ_changedSlider
}
}
else {
for allUnchangedSliders {
// use weight factor to change proportionally
Δi = – v_i / ∑(v_i) * Δ_changedSlider
}
}
Please be aware that you must cache the values of the current state of your sliders at the beginning or (even better) first compute all the changes and then apply all the changes in a batch. Otherwise you will use a value v2' that you just computed for determining the value v3' which will obviously result in incorrect values.
Hey #Sean the simplest adjustment that I could think of here is to check if the remainingStartVals is not 0 that means that there are weights assigned to the other sliders and also check if a single slider had a weight to begin with which means its startVal shouldn't be equal to 0
func calcNewVal(startVal: Float, changerStartVal: Float) -> Float{
var endVal = 0
let remainingStartVals = globalTotal - changerStartVal
if remainingStartVals != 0 || startVal != 0{
let remainingNewVals = globalTotal - changer.value
endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
}
return endVal
}

Missing numbers in nsarray

Good day, For example: If I have an nsarray [3, 1, -5, 3, 3, -5, 0, 1, 1, 3]
How do I calculate Missing numbers in my Array:
-4
-3
-2
-1
2
But - No sorting is allowed and must run in linear time O(N)
Well the brute force way would be something like this
a. find the max and min values in the array -5, 3
b. loop multiple times the array form -5 to 3 looking for the specific number (-5, -4, -3, -2, -1, 0 .... 3)
b1. if the number if found break that loop and continue with the next
b2 . if the loop ends without breaking take note of that number
It's inefficient compared to just sorting it, but it runs in a linear way
The idea is to make another array of bools and to check true if that number exist. After you do that, just go through array of bools and if number is false then its missing.
plz use this code
NSArray *a = #[#3, #1, #-5, #3, #3, #-5, #0, #1, #1, #3];
NSNumber *max=[a valueForKeyPath:#"#max.self"];
NSNumber *min=[a valueForKeyPath:#"#min.self"];
int big = [max intValue];
int small = [min intValue];
while (small<=big) {
if ([a containsObject:[NSNumber numberWithInt:small]]) {
}
else
{
NSLog(#"missing number is %d",small);
}
small++;
}
result
If the numbers in the array are consecutive integers, then 'Sort' the array and find the difference between the two consecutive numbers. If it is 1, then the number is not missed. Else, the number has missed.

generating series of number 0,3,5,8,10,13,15,18

i want to generate a series of number through looping.
my series will contain numbers like 0,3,5,8,10,13,15,18 and so on.
i try to take reminder and try to add 2 and 3 but it wont work out.
can any one please help me in generating this series.
You can just use an increment which toggles between 3 and 2, e.g.
for (i = 0, inc = 3; i < 1000; i += inc, inc = 5 - inc)
{
printf("%d\n", i);
}
It looks like the the sequence starts at zero, and uses increments of 3 and 2. There are several ways of implementing this, but perhaps the simplest one would be iterating in increments of 5 (i.e. 3+2) and printing two numbers - position and position plus three.
Here is some pseudocode:
i = 0
REPEAT N times :
PRINT i
PRINT i + 3
i += 5
The iteration i=0 will print 0 and 3
The iteration i=5 will print 5 and 8
The iteration i=10 will print 10 and 13
The iteration i=15 will print 15 and 18
... and so on
I was pulled in with the tag generate-series, which is a powerful PostgreSQL function. This may have been tagged by mistake (?) but it just so happens that there would be an elegant solution:
SELECT ceil(generate_series(0, 1000, 25) / 10.0)::int;
generate_series() returns 0, 25, 50, 75 , ... (can only produces integer numbers)
division by 10.0 produces numeric data: 0, 2.5, 5, 7.5, ...
ceil() rounds up to your desired result.
The final cast to integer (::int) is optional.
SQL Fiddle.

How to get the vertical and horizontal alignment by an integer?

I'm trying to convert an integer value to a content alignment. The integer can hold both a horizontal and a vertical alignment at the same time.
First I created an enum, which describes all possibilities (i have to use the values of android Gravity class: http://developer.android.com/reference/android/view/Gravity.html)
typedef enum{
GravityHorizontalCenter = 1, // (0x00000001)
GravityLeft = 2, // (0x00000002)
GravityRight = 5, // (0x00000005)
GravityVerticalCenter = 16, // (0x00000010)
GravityTop = 48, // (0x00000030)
GravityBottom = 80, // (0x00000050)
} GravityType;
So int alignment = GravityRight | GravityTop would be 53.
I want to check the alignment of my view-objects like this:
if ((textAlignment & GravityHorizontalCenter) == GravityHorizontalCenter){
return NSTextAlignmentCenter;
}...
But there seems to be something missing, because for 53 the if statement textAlignment & GravityHorizontalCenter) == GravityHorizontalCenter returns True.
You need masks for the the Vertical and Horizontal ranges.
typedef enum{
GravityHorizontalCenter = 1, // (0x00000001)
GravityLeft = 2, // (0x00000002)
GravityRight = 5, // (0x00000005)
GravityHorizontalMask = 7, // (0x00000007)
GravityVerticalCenter = 16, // (0x00000010)
GravityTop = 48, // (0x00000030)
GravityBottom = 80, // (0x00000050)
GravityVerticalMask = 112, // (0x00000070)
} GravityType;
Then you can do a test with:
(textAlignment & GravityHorizontalMask) == GravityHorizontalCenter
or
(textAlignment & GravityVerticalMask) == GravityTop
These values are only really suitable for direct comparison, since 5 (101 binary) and 1 (001 binary) overlap as bit masks. But since you are storing two values in the same number (the first 4 bits for the horizontal alignment, and the second 4 bits for the vertical alignment), you need a mask to isolate the range of bits that you want to compare.
Also, you should be aware that on Android the value of LEFT (the left gravity constant) is 3 and not 2. So if your enum really needs to be compatible with Android then your GravityLeft value is probably incorrect.
Because these values are not suited for being used as bit flags (masks).
& is not magic - it's just the bitwise AND operator. And if you bitwise AND a number with 1 then you compare the result to 1, that only checks if the least significant bit was set in the original number, i. e. if it was odd. Thus, (textAlignment & GravityHorizontalCenter) == GravityHorizontalCenter will yield true for any odd number.
If you want to use numbers as flags, you have to make them different powers of two, like this:
GravityHorizontalCenter = 1,
GravityLeft = 2,
GravityRight = 4,
GravityVerticalCenter = 8,
GravityTop = 16,
GravityBottom = 32,

Scaling a number between two values

If I am given a floating point number but do not know beforehand what range the number will be in, is it possible to scale that number in some meaningful way to be in another range? I am thinking of checking to see if the number is in the range 0<=x<=1 and if not scale it to that range and then scale it to my final range. This previous post provides some good information, but it assumes the range of the original number is known beforehand.
You can't scale a number in a range if you don't know the range.
Maybe what you're looking for is the modulo operator. Modulo is basically the remainder of division, the operator in most languages is is %.
0 % 5 == 0
1 % 5 == 1
2 % 5 == 2
3 % 5 == 3
4 % 5 == 4
5 % 5 == 0
6 % 5 == 1
7 % 5 == 2
...
Sure it is not possible. You can define range and ignore all extrinsic values. Or, you can collect statistics to find range in run time (i.e. via histogram analysis).
Is it really about image processing? There are lots of related problems in image segmentation field.
You want to scale a single random floating point number to be between 0 and 1, but you don't know the range of the number?
What should 99.001 be scaled to? If the range of the random number was [99, 100], then our scaled-number should be pretty close to 0. If the range of the random number was [0, 100], then our scaled-number should be pretty close to 1.
In the real world, you always have some sort of information about the range (either the range itself, or how wide it is). Without further info, the answer is "No, it can't be done."
I think the best you can do is something like this:
int scale(x) {
if (x < -1) return 1 / x - 2;
if (x > 1) return 2 - 1 / x;
return x;
}
This function is monotonic, and has a range of -2 to 2, but it's not strictly a scaling.
I am assuming that you have the result of some 2-dimensional measurements and want to display them in color or grayscale. For that, I would first want to find the maximum and minimum and then scale between these two values.
static double[][] scale(double[][] in, double outMin, double outMax) {
double inMin = Double.POSITIVE_INFINITY;
double inMax = Double.NEGATIVE_INFINITY;
for (double[] inRow : in) {
for (double d : inRow) {
if (d < inMin)
inMin = d;
if (d > inMax)
inMax = d;
}
}
double inRange = inMax - inMin;
double outRange = outMax - outMin;
double[][] out = new double[in.length][in[0].length];
for (double[] inRow : in) {
double[] outRow = new double[inRow.length];
for (int j = 0; j < inRow.length; j++) {
double normalized = (inRow[j] - inMin) / inRange; // 0 .. 1
outRow[j] = outMin + normalized * outRange;
}
}
return out;
}
This code is untested and just shows the general idea. It further assumes that all your input data is in a "reasonable" range, away from infinity and NaN.

Resources