How to Check Double value is Null or Zero in kotlin
val ratio:Double? = 0.0
val calRatio = if (ratio == null || ratio == 0.0)
0.12
else
ratio
ratio in null , 0.0 , 0.1
if ratio null or 0.0 then return 0.12
and ratio is 0.2 or more then return same ratio value
how to check this algorithm not use if statement
You can write this in idomatic Kotlin without an if statement using takeUnless.
val ratio: Double? = 0.0
val calRatio = ratio.takeUnless { it == 0.0 } ?: 0.12
The takeUnless call checks whether the number matches the predicate it == 0.0. If the predicate evaluates to true, null is returned. Only when the predicate evaluates to false is the actual number returned.
We can see why this works by considering the three possible cases:
When ratio is null, the predicate it == 0.0 evaluates to false. The call to ratio.takeUnless { it == 0.0 } returns the value of ratio, which is null. Because its left-hand-side operand is null, the ?: operator returns the right-hand-side value of 0.12.
When ratio is 0.0, the predicate it == 0.0 evaluates to true. The call to ratio.takeUnless { it == 0.0 } ignores the value of ratio and instead returns null. Because its left-hand-side operand is null, the ?: operator returns the right-hand-side value of 0.12.
When ratio is any non-null, non-zero number, the predicate it == 0.0 evaluates to false. The call to ratio.takeUnless { it == 0.0 } returns the value of ratio, which is the original number. Because its left-hand-side operand is not null, the ?: operator returns the left-hand-side value.
Related
When implementing the ReLU function for AutoDiff, one of the methods used is the std::max function; other implementations (conditional statements) work correctly but a try to implement max functions returns only 0 in the whole range.
On input vector:
dual in[] = { -3.0, -1.5, -0.1, 0.1, 1.5, 3.0 }
the derivative call in the form
derivative(ReLU,wrt(y),at(y)) where y = in[i]
gives proper results if ReLU is implemented with:
dual ReLU_ol(dual x) {
return (x > 0) * x; // ok; autodiff gives x > 0 ? 1 : 0
}
dual ReLU_if(dual x) {
if (x > 0.0) {
return x;
} else {
return 0.0;
}
// ok; autodiff gives x > 0 ? 1 : 0
}
that is (regarding derivative) one if x > 0 and zero elsewhere.
When ReLU is implemented in the form:
dual ReLU_max(dual x) {
return std::max(0.0,(double)x); // results an erroneous result of derivative
}
as result, I get zero in the whole range.
I expect that std::max (or std::min) should be prepared correctly for automatic differentiation.
Am I doing something wrong or maybe I miss understand something?
The resulting plot is:
where d / dx is calculated with AutoDiff; purple and blue lines are overlapping; results for ReLU_ol are not plotted.
i have a container which stores double values from a source, and i need to find the location of numbers when it appears in a specific order/pattern.
vector<double> m = {-0.15,0.2,-0.2,-0.1,0.5,-0.15,-0.8,0.35,-0.2,-0.35......nth}
is there any way to find the location of numbers, if the appear in a order(in sequence) like:
m[x] = 0.1 to 0.5 //value of m[x] must between those two values
m[x+1] = 0.35 to 0.7 //anywhere between the range
m[x+2] = -0.1 to 0.1 // "
m[x+3] = 0.0 to.03 // "
std::search with a custom predicate.
Your pattern would contain ranges, and you need a custom binary predicate returning true if the LHS double lies in the RHS range.
Un-tested example:
using Range = std::pair<double,double>;
std::vector<Range> pattern {{0.1, 0.5}, {0.35, 0.7}, {-0.1, 0.1}, {0.0, 0.03}};
auto match = std::search(begin(m), end(m),
begin(pattern), end(pattern),
[](double d, Range r) {
return (r.first < d) && (d < r.second);
});
Add appropriate epsilon for your double comparisons, etc. etc.
The C++ program below should return a stricly positive value. However, it returns 0.
What happens ? I suspect an int-double conversion, but I can't figure out why and how.
#include <iostream>
#include <vector>
#include <numeric>
using namespace std;
int main()
{
vector<double> coordinates;
coordinates.push_back(0.5);
coordinates.push_back(0.5);
coordinates.push_back(0.5);
cout<<inner_product(coordinates.begin(), coordinates.end(), coordinates.begin(), 0)<<endl;
return 0;
}
Because you've supplied an initial value of 0, an int. Your code is internally equivalent to:
int result = 0;
result = result + 0.5 * 0.5; // first iteration
result = result + 0.5 * 0.5; // second iteration
result = result + 0.5 * 0.5; // third iteration
return result;
While result + 0.5 * 0.5 produces the correct value (result is promoted to double in this expression), when that value is assigned back into result, it's truncated (that expression is cast to int). You never get above 1, so you see 0.
Give it an initial value of 0.0 instead.
This is because you provided zero as an integer constant. The resultant operations are all in integers, so the final value (0.75) is truncated to an int as well.
Change zero to 0.0 to make it work:
cout << inner_product(coord.begin(), coord.end(),coord.begin(), 0.0) << endl;
This produces 0.75 on ideone.
I have a problem with my code where agents moving around suddenly disappear. This seems to be because their positions suddenly become 1.#INF000 in the x and y axis. I did a little research and someone said this can occur with acos if a value is over or under 1 and -1 respectively, but went on to say it could happen if the values were close too. I added an if statement to check to see if I'm ever taking acos of 1 or -1 and it does evaluate to 1 a few frame cycles before they disappear, however I don't really understand the problem to be able to fix it. Can anyone shed any light on this matter?
D3DXVECTOR3 D3DXVECTOR3Helper::RotToTarget2DPlane(D3DXVECTOR3 position, D3DXVECTOR3 target)//XY PLANE
{
//Create std::vector to target
D3DXVECTOR3 vectorToTarget = target - position;
D3DXVec3Normalize(&vectorToTarget, &vectorToTarget);
//creates a displacement std::vector of relative 0, 0, 0
D3DXVECTOR3 neutralDirectionalVector = D3DXVECTOR3(1, 0, 0);//set this to whatever direction your models are loaded facing
//Create the angle between them
if(D3DXVec3Dot(&vectorToTarget, &neutralDirectionalVector) >= 1.0f ||D3DXVec3Dot(&vectorToTarget, &neutralDirectionalVector) <= -1.0f)
{
float i = D3DXVec3Dot(&vectorToTarget, &neutralDirectionalVector);
float j = 0; //ADDED THIS IF STATEMENT
}
float angle = acos(D3DXVec3Dot(&vectorToTarget, &neutralDirectionalVector));
if (target.y > position.y)
{
return D3DXVECTOR3(0, 0, angle);
}
else
{
return D3DXVECTOR3(0, 0, -angle);
}
}//end VecRotateToTarget2DPlane()
It is dangerous to call acos on a value that may be exactly +/-1.0, because rounding errors can cause the computed value to be outside this range.
But it's easy to fix -- use this function instead:
double SafeAcos (double x)
{
if (x < -1.0) x = -1.0 ;
else if (x > 1.0) x = 1.0 ;
return acos (x) ;
}
man page for acos tells this :
On success, these functions return the arc cosine of x in radians; the
return value is in the range [0, pi].
If x is a NaN, a NaN is returned.
If x is +1, +0 is returned.
If x is positive infinity or negative infinity, a domain error occurs,
and a NaN is returned.
If x is outside the range [-1, 1], a domain error occurs, and a NaN is
returned.
This means that for a value outside of the [-1,+1] range, the value is not a number. That also corresponds to how the acos is defined.
As mentioned above (by #TonyK) , acos is not defined outside the range [-1,+1].
First, you should check why the issue exists, aka: Why is my argument out of range? Maybe there is some issue with the calculation of your argument.
If you worked that out, you can use the SafeAcos proposed by TonyK.
As we do know that acos(-1.0) = π and acos(1.0) = 0,
I suggest a little modification (for performance reasons):
double SafeAcos (double x)
{
if (x <= -1.0)
return MATH_PI;
else if(x >= 1.0)
return 0;
else
return acos (x) ;
}
Where MATH_PI = 3.14...
I am having trouble with a C++ object-orientated script. When I create an object, I wish to calculate an AttributeQ based on its attributes MyAValue, MyBValue, and MyCValue.
While using the Visual 2010 debugger, I noticed that TempAttribueQ seems to always be 0 (except before it is initialized of course). Assuming Delta != 0, BVal == Maximum, and DeltaA == DeltaC, then TempAttribueQ should be 1/3 not 0.
At first I thought it was a scope problem, but the variable is defined outside the if-else statements. I have tried initializing TempAttribueQ as some outrageous number, which it keeps up until the if-else statements when it becomes 0 when it shouldn't.
This is my code...
void SetMyAttribueQ(){
double TempAVal = MyAValue;
double TempBVal = MyBValue;
double TempCVal = MyCValue;
double Minimum = min(min(TempAVal, TempBVal), TempCVal);
double Maximum = max(max(TempAVal, TempBVal), TempCVal);
double Delta = Maximum - Minimum;
double DeltaA = 0;
double DeltaB = 0;
double DeltaC = 0;
double TempAttribueQ = 0;
if(Delta == 0) {
MyAttribueQ = TempAttribueQ; // this->SetMyAttribueQ(TempAttribueQ);
}
else {
DeltaA = /* (a removed equation goes here... */
DeltaB = /* (a removed equation goes here... */
DeltaC = /* (a removed equation goes here... */
if(AVal == Maximum)
TempAttribueQ = (DeltaC - DeltaB);
else if(BVal == Maximum)
TempAttribueQ = (1/3) + (DeltaA - DeltaC);
else
TempAttribueQ = (2/3) + (DeltaB - DeltaA);
MyAttribueQ = TempAttribueQ;
}
}
What is preventing TempAttribueQ from getting a value of 1/3 or 2/3? Or, what is causing it to be set to be set to 0?
When you divide one integer by another, you get an integer result. Change either or both the constants to non-integer to fix it - C++ rules will result in the other being converted to floating point before the division takes place. All of the following will work:
1.0 / 3.0
1 / 3.0
1.0 / 3
An integer will get converted back to a double invisibly, which is why you weren't seeing any errors in your code.
1 is an integer and 3 is an integer so 1/3 uses integer arithmetic.
You want to use 1.0/3.0 to force double precision arithmetic.
1/3 == 0 due to integer division, which is set to TempAttribueQ.
You need to do 1./3 which will produce 0.3333333..
Try 1.0/3.0 and 2.0/3.0. 1/3 and 2/3 are 0 due to integer division.