argmax of a function allowing small violations - math

I have a function that returns an object with the best rating among a set of objects.
Now I want to get the object with the best rating which is closest to a certain point. Basically I want to allow a small violation to the formula, such that if o_1 is closer to the given point than o_2 even if
if
for some small and fixed
Currently I achieve with a about 5 if statements in a program, but I was wondering if there's a way to represent this in a cleaner more elegant way with a mathematical formula perhaps? If you have ever had a problem like this, how did you code it?
Here is a snippet of the code I have, I know there are some refactorizations that could be done to the if statements, I wanted to make the cases clearer. Is there a more elegant way of solving this?
public VisualDevice MostSuitableDevice(GameObject u, GameObject t, List<VisualDevice> D)
{
float maxSuitability = 0;
VisualDevice mostSuitableDevice = null;
float epsMaxSuitability = 0;
VisualDevice epsMSD = null;
foreach (VisualDevice d in D)
{
float suitability = Rating(d, u, t);
bool closerDevice = mostSuitableDevice != null ? Vector3.Distance(d.GetLightPosition(), t.transform.position) < Vector3.Distance(mostSuitableDevice.GetLightPosition(), t.transform.position) : false;
if (suitability > maxSuitability && closerDevice)
{
maxSuitability = suitability;
mostSuitableDevice = d;
}
else if (suitability > maxSuitability + epsilon)
{
maxSuitability = suitability;
mostSuitableDevice = d;
}
else if (suitability + epsilon > maxSuitability && closerDevice)
{
closerDevice = epsMSD != null ? Vector3.Distance(d.GetLightPosition(), t.transform.position) < Vector3.Distance(epsMSD.GetLightPosition(), t.transform.position) : false;
if (suitability > epsMaxSuitability && closerDevice)
{
epsMaxSuitability = suitability;
epsMSD = d;
}
else if (suitability > epsMaxSuitability + epsilon)
{
epsMaxSuitability = suitability;
epsMSD = d;
}
else if (suitability + epsilon > epsMaxSuitability && closerDevice)
{
epsMaxSuitability = suitability;
epsMSD = d;
}
}
}
bool epsCloser = epsMSD != null && mostSuitableDevice!=null ? Vector3.Distance(epsMSD.GetLightPosition(), t.transform.position) < Vector3.Distance(mostSuitableDevice.GetLightPosition(), t.transform.position) : false;
if (epsMaxSuitability + epsilon > maxSuitability && epsCloser)
{
maxSuitability = epsMaxSuitability;
mostSuitableDevice= epsMSD;
}
return mostSuitableDevice;
}

First find maximum rating rmax. Then select the object closest to the given point from all objects o with Rating(o) >= rmax - epsilon.
Like that:
float maxSuitability = D.Max( d => Rating(d, u, t));
float minDistance = float.PositiveInfinity;
VisualDevice mostSuitableDevice = null;
foreach (VisualDevice d in D)
{
float suitability = Rating(d, u, t);
if (suitability < maxSuitability - epsilon)
continue;
float distance = Vector3.Distance(...
if (distance < minDistance)
{
minDistance = distance;
mostSuitableDevice = d;
}
}

Related

Can someone explain the mistake in this code? Leetcode 44 Wildcard Matching

Can Someone explain what is wrong in this code ?
It is failing on testcase s = "aa" and p = "*".
I have followed recursion and dynamic programming code here
Leetcode 44 Wildcard Matching
class Solution {
public boolean isMatch(String s, String p) {
int n = s.length();
int m = p.length();
int[][] dp = new int[n][m];
for(int[] it : dp)
Arrays.fill(it, -1);
return solve(n-1 , m-1, s ,p , dp);
}
public boolean solve(int i, int j, String s, String p, int[][] dp){
if(i < 0 && j < 0) return true;
if(i < 0 && j >=0){
while(j>=0){
if(p.charAt(j) + "" == "*") j--;
else return false;
}
return true;
}
if(j < 0 && i >=0) return false;
if(dp[i][j] != -1){
if(dp[i][j]==1) return true;
return false;
}
if(s.charAt(i) == p.charAt(j) || p.charAt(j) + "" == "?"){
boolean temp = solve(i-1,j-1,s,p,dp);
if(temp == false) dp[i][j] = 0;
else
dp[i][j] = 1;
return temp;
}
if(p.charAt(j) + "" == "*"){
boolean temp = solve(i-1,j,s,p,dp) || solve(i,j-1,s,p,dp);
if(temp == false)
dp[i][j] = 0;
else
dp[i][j] = 1;
return temp;
}
dp[i][j] = 0;
return false;
}
}

What is causing the buffer overrun error in below code

Unable to figure out what is causing the buffer overflow in below code. I reckon it has to do with the vector but I am guarding against out of bounds access. Is there anything else that could be causing the overflow?
class Solution {
public:
bool canPartition(vector<int>& nums) {
int sum = 0;
bool canPartition = true;
vector<vector<int>> dp(nums.size(), vector<int>(sum / 2 + 1, -1));
sum = accumulate(nums.begin(),nums.end(),0);
if (sum % 2 != 0)
{
canPartition = false;
}
if (true == canPartition)
{
canPartition = canPartitionRecursive(nums, 0, sum/2, dp);
}
return canPartition;
}
bool canPartitionRecursive(vector<int>& nums, int index, int sum,
vector<vector<int>>& dp)
{
if (sum == 0)
{
return true;
}
if (index >= nums.size() || sum < 0)
{
return false;
}
if (dp[index][sum] != -1)
{
if (true == canPartitionRecursive(nums, index+1, sum - nums[index],dp))
{
dp[index][sum] = 1;
return true;
}
dp[index][sum] = canPartitionRecursive(nums, index + 1, sum, dp);
}
return dp[index][sum] = 1? true:false;
}
};
This looks like a transpositional error (all subvector will have size 1):
int sum = 0;
vector<vector<int>> dp(nums.size(), vector<int>(sum / 2 + 1, -1));
sum = accumulate(nums.begin(),nums.end(),0);
Perhaps calculation of sum should be moved before dp initialization?

Algorithm implemented with openCL working till size exceeds 768

I've implemented sorting algorithm using openCL. Its using one work group per array to sort (arrays are connected in __global float *array, all have the same size).
Im testing results using 200 random arrays and result are deterministic.
With one parameter, its working correctly till array size exceeds of array 768
With two parameters, its working correctly till arrays size exceeds 768
With three parameters, its working correctly till arrays size exceeds 317
What could be the reason of correct processing of just 768 (CL_KERNEL_WORK_GROUP_SIZE returns 1024 elements). Is it some memory constraints? What is the best way of invastigation such issue?
Gpu specs (4th answer):
Kernel code below:
__kernel void assort(
__global float *array,
__local float *currentOutput,
__local float *stimulations,
__local int *noOfValuesAdded,
__local float *addedValue,
__local float *positionToInsert,
__local int *activatedIdx,
__local float *range,
int size
) {
int id = get_local_id(0);
int gid = get_group_id(0);
if (id == 0)
{
if (array[gid*size]<array[gid*size+1])
{
currentOutput[0] = array[gid*size];
currentOutput[1] = array[gid*size + 1];
}
else
{
currentOutput[1] = array[gid*size];
currentOutput[0] = array[gid*size + 1];
}
noOfValuesAdded[0] = 2;
}
barrier(CLK_LOCAL_MEM_FENCE);
for (int i = 2; i < size; i++)
{
int maxIdx = noOfValuesAdded[0] - 1;
if (id == 0)
{
addedValue[0] = array[gid*size + i];
positionToInsert[0] = -100.0f;
activatedIdx[0] = -2;
range[0] = currentOutput[maxIdx] - currentOutput[0];
}
barrier(CLK_LOCAL_MEM_FENCE);
if (id < noOfValuesAdded[0])
{
if (id == 0)
{
stimulations[id] = (currentOutput[maxIdx] - addedValue[0]) / range[0];
float stimulation = stimulations[id];
if ( fabs(stimulation - 1.0f) < 0.000001)
activatedIdx[0] = 0;
else if (stimulation > 1.0f)
{
activatedIdx[0] = -1;
}
}
else if (id == maxIdx)
{
stimulations[maxIdx] = (addedValue[0] - currentOutput[0]) / range[0];
float stimulations = (addedValue[0] - currentOutput[0]) / range[0];
if ( fabs(stimulations - 1.0f) < 0.000001 )
activatedIdx[0] = maxIdx;
else
if (stimulations > 1)
activatedIdx[0] = maxIdx + 1;
}
else
{
stimulations[id] = 1.0f - (fabs((currentOutput[id] - addedValue[0])) / range[0]);
if ( fabs(stimulations[id] - 1.0f) < 0.000001)
activatedIdx[0] = id;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (activatedIdx[0] == -2 && id < noOfValuesAdded[0])
{
if (noOfValuesAdded[0] == 2)
{
positionToInsert[0] = 0.9f;
}
else if (id != 0 &&
id != maxIdx &&
stimulations[id] >= stimulations[(id - 1)] &&
stimulations[id] >= stimulations[(id + 1)] )
{
if ((1.0f - (fabs(currentOutput[(id - 1)] - currentOutput[id]) / range[0]) ) < stimulations[(id - 1)])
positionToInsert[0] = (float)id - 0.1f;
else
positionToInsert[0] = (float)id + 0.9f;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (activatedIdx[0] == -2)
{
if (id == 0 && positionToInsert[0] < -90.0f) // default value maintained
{
if (stimulations[0] > stimulations[1])
positionToInsert[0] = 0.9f;
else
positionToInsert[0] = (float)maxIdx - 0.1f;
}
}
else
{
if (activatedIdx[0] == -1)
positionToInsert[0] = -0.1f;
else if (activatedIdx[0] == (maxIdx + 1))
{
positionToInsert[0] = (float)maxIdx + 0.9f;
}
else
{
currentOutput[activatedIdx[0]] = addedValue[0];
}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (positionToInsert[0] > -50.0f) // default value changed
{
float temp = 0.0f;
if ((float)id>positionToInsert[0])
{
temp = currentOutput[id];
currentOutput[id + 1] = temp;
}
barrier(CLK_LOCAL_MEM_FENCE);
if ((float)id > positionToInsert[0])
{
temp = currentOutput[id];
}
barrier(CLK_LOCAL_MEM_FENCE);
if (id == round(positionToInsert[0]))
{
currentOutput[id] = addedValue[0];
noOfValuesAdded[0] = noOfValuesAdded[0] + 1;
}
}
barrier(CLK_LOCAL_MEM_FENCE);
}
barrier(CLK_LOCAL_MEM_FENCE);
array[gid*size + id] = currentOutput[id];
return;
}

Inside boundaries

I'm using this article to write a fluid simulation application.
I can't manage to implement the inside boundaries. As far as i know when I'm setting the boundaries (in the set_bnd function) for each cell that is inside the boundary I should calculate the average value from the adjacent non-boundary cells like this:
for (i = 0 ; i < n ; i++)
{
for (j = 0 ; j < n ; j++)
{
if (isBoundary(i,j)
{
sum = 0;
count = 0;
if (!isBoundary(i+1,j) {
sum += x[i+1][j];
}
if (!isBoundary(i-1,j) {
sum += x[i-1][j];
}
if (!isBoundary(i,j+1) {
sum += x[i][j+1];
}
if (!isBoundary(i,j-1) {
sum += x[i-1][j];
}
x[i][j] = sum / 4;
}
}
}
Unfortunately the smoke is absorbed and disappears in contact with boundary surface.
My math background is not sufficient to understand every part of the calculation, so I'll be very grateful if someone points me the right direction.
Here is some code to explain further.
insideBound is array (1 - boundary, 0 - empty, the fluid can pass trough)
#define FOR_EACH_CELL for ( i=1 ; i<=N ; i++ ) { for ( j=1 ; j<=N ; j++ ) {
void set_bnd ( int N, int b, float * x, int * insideBound )
{
int i, j;
float sum;
int count;
for ( i=1 ; i<=N ; i++ ) {
x[IX(0 ,i)] = b==1 ? -x[IX(1,i)] : x[IX(1,i)];
x[IX(N+1,i)] = b==1 ? -x[IX(N,i)] : x[IX(N,i)];
x[IX(i,0 )] = b==2 ? -x[IX(i,1)] : x[IX(i,1)];
x[IX(i,N+1)] = b==2 ? -x[IX(i,N)] : x[IX(i,N)];
}
x[IX(0 ,0 )] = 0.5f*(x[IX(1,0 )]+x[IX(0 ,1)]);
x[IX(0 ,N+1)] = 0.5f*(x[IX(1,N+1)]+x[IX(0 ,N)]);
x[IX(N+1,0 )] = 0.5f*(x[IX(N,0 )]+x[IX(N+1,1)]);
x[IX(N+1,N+1)] = 0.5f*(x[IX(N,N+1)]+x[IX(N+1,N)]);
if (!b) return;
FOR_EACH_CELL
sum = 0.0f;
count = 0;
if (insideBound[IX(i,j)] == 1)
{
if (insideBound[IX(i-1,j)] != 1)
{
count++;
sum = sum + x[IX(i-1,j)];
}
if (insideBound[IX(i+1,j)] != 1)
{
count++;
sum = sum + x[IX(i+1,j)];
}
if (insideBound[IX(i,j-1)] != 1)
{
count++;
sum = sum + x[IX(i, j-1)];
}
if (insideBound[IX(i,j+1)] != 1)
{
count++;
sum = sum + x[IX(i, j+1)];
}
if (count > 0)
{
x[IX(i,j)] = -sum / count;
} else {
x[IX(i,j)] = 0;
}
}
END_FOR
}
Per book (working):
In the first loop are set top, right, bottom and left boundary cells.
Since for them there is only one adjacent cell that is not bound the cell get its value. (I don't know why its opposite for U and the same value for V)
After the first loop, the corner boundary values are set. Here they get average values from their adjacent cells (i guess since there is no adjacent cell that is not boundary they use boundary cells).
Mine, not working properly:
if (!b) return - ignores calculations for density and updates only velocity.
The loop calculates the values for all boundary cells (again, average values from the adjacent cells that are not boundaries themselves).
I get almost realistic result from this methods, but there is big loses in the density and some bugs with too big boundaries where the fluid disappears completely.
I've managed to find a solution, here it is for potential people with the same problem
void set_bnd ( int N, int b, float * x, int * insideBound )
{
int i, j;
float sum, tmp;
int count;
for ( i=1 ; i<=N ; i++ ) {
x[IX(0 ,i)] = b==1 ? -x[IX(1,i)] : x[IX(1,i)];
x[IX(N+1,i)] = b==1 ? -x[IX(N,i)] : x[IX(N,i)];
x[IX(i,0 )] = b==2 ? -x[IX(i,1)] : x[IX(i,1)];
x[IX(i,N+1)] = b==2 ? -x[IX(i,N)] : x[IX(i,N)];
}
x[IX(0 ,0 )] = 0.5f*(x[IX(1,0 )]+x[IX(0 ,1)]);
x[IX(0 ,N+1)] = 0.5f*(x[IX(1,N+1)]+x[IX(0 ,N)]);
x[IX(N+1,0 )] = 0.5f*(x[IX(N,0 )]+x[IX(N+1,1)]);
x[IX(N+1,N+1)] = 0.5f*(x[IX(N,N+1)]+x[IX(N+1,N)]);
if (!b) return;
for ( i=1 ; i<=N ; i++ ) {
for ( j=1 ; j<=N ; j++ ) {
sum = 0.0f;
count = 0;
if (insideBound[IX(i,j)] == 1)
{
if (insideBound[IX(i-1,j)] != 1)
{
count++;
if (b == 2)
tmp = -x[IX(i-1,j)];
else
tmp = x[IX(i-1,j)];
sum = sum + tmp;
}
if (insideBound[IX(i+1,j)] != 1)
{
count++;
if (b == 2)
tmp = -x[IX(i+1,j)];
else
tmp = x[IX(i+1,j)];
sum = sum + tmp;
}
if (insideBound[IX(i,j-1)] != 1)
{
count++;
if (b == 1)
tmp = - x[IX(i, j-1)];
else
tmp = x[IX(i, j-1)];
sum = sum + tmp;
}
if (insideBound[IX(i,j+1)] != 1)
{
count++;
if (b == 1)
tmp = -x[IX(i, j+1)];
else
tmp = x[IX(i, j+1)];
sum = sum + tmp;
}
if (count > 0)
{
x[IX(i,j)] = -sum / count;
} else {
x[IX(i,j)] = 0;
}
}
}
}
}
insideBound is boolean array (0,1) which indicates the cells that are boundaries. Works with one or more boundary areas, but they should be at least 3 cells wide and high.

vector iterator not dereferncable....?

`void calc_distance(vector fingerTips, CvPoint palmCenter,IplImage *source)
{
double distance = 0;
vector<CvPoint>::iterator p;
if (fingerTips.size() != NULL && fingerTips.size() <= 5 && fingerTips.size() >= 1)
{
if ((fingerTips.size() > 1) || (fingerTips.size() <= 5))
{
distance = 0;
p = fingerTips.begin();
CvPoint forefinger = *p;
CvPoint secondfinger;
for( ;p != fingerTips.end(); )
{
p++;
secondfinger = *p;
distance += sqrt(double((forefinger.x - secondfinger.x) *
(forefinger.x - secondfinger.x) + (forefinger.y - secondfinger.y) * (forefinger.y - secondfinger.y)) );
cvLine(source,forefinger,secondfinger,cvScalar(1.0,1.0,1.0),3,8);
forefinger = secondfinger;
}
}
}
}
//as parameters i passed the the vector of fingertips co-ordinate and the center of the palm along with image source
but still im getting the error: "vector iterator not differefercable"....
the error occurs in the 2nd iteration at " secondfinger = *p;" line.....
please help me.....
here i am trying to get distance between each fingers and summing each of the them to get
the final distance....
please help me...
You check p != end, then P++, then dereference. You should just do a standard for loop:
for(; p != fingerTips.end(); p++)
{
//p++ //This is gone now. It's up in the for loop
...
}
instead of having p++ in your for loop
You need to dereference p before you increment it; otherwise, you end up trying to dereference fingertips.end() when you get to the end of the collection, which cannot be dereferenced.
for( ;p != fingerTips.end(); ++p)
{
secondfinger = *p;
distance += sqrt(double((forefinger.x - secondfinger.x) * (forefinger.x - secondfinger.x) + (forefinger.y - secondfinger.y) * (forefinger.y - secondfinger.y)) );
cvLine(source,forefinger,secondfinger,cvScalar(1.0,1.0,1.0),3,8);
forefinger = secondfinger;
}

Resources