ceres solver analytical derivative doesn't work - optimization

template<typename ConcreteOccGridMapUtil>
class getResidual : public ceres::SizedCostFunction<1,3>
{
public:
ConcreteOccGridMapUtil* occ;
DataContainer dataPoints;
getResidual(ConcreteOccGridMapUtil* occ, const DataContainer& dataPoints)
{
this->occ = occ;
this->dataPoints = dataPoints;
}
virtual ~getResidual() {}
virtual bool Evaluate(double const* const* parameters,
double* residuals,
double** jacobians) const
{
Eigen::Matrix<double, 3, 1> pose1(parameters[0][0],parameters[0][1],parameters[0][2]);
Eigen::Vector3f pose = pose1.cast<float>();
Eigen::Affine2f transform(occ->getTransformForState(pose)); // transform: rotation->translation
float sinRot = std::sin(pose[2]);
float cosRot = std::cos(pose[2]);
int size = dataPoints.getSize();
residuals[0] = 0;
jacobians[0][0]=0;
jacobians[0][1]=0;
jacobians[0][2]=0;
for (int i = 0; i < size; ++i)
{
const Eigen::Vector2f& currPoint (dataPoints.getVecEntry(i)); /// lidar point
Eigen::Vector3f transformedPointData(occ->interpMapValueWithDerivatives(transform * currPoint)); /// {M,dM/dx,dM/dy}
float funVal = 1.0f - transformedPointData[0];
// float weight=util::WeightValue(funVal);
float weight=1.0;
residuals[0] += static_cast<double>(funVal);
jacobians[0][0] += static_cast<double>(transformedPointData[1]);
jacobians[0][1] += static_cast<double>(transformedPointData[2]);
double rotDeriv = ((-sinRot * currPoint.x() - cosRot * currPoint.y()) * transformedPointData[1] + (cosRot * currPoint.x() - sinRot * currPoint.y()) * transformedPointData[2]);
jacobians[0][2] += static_cast<double>(rotDeriv);
}
return true;
}
};
my parameter to optimize is the pose = [x,y,theta]
my objective function is to minimize the occupancy value about pose and laser point. And here I add them manually together into residuals[0]
I have 3 parameters [x,y,theta] so my jacobians have 3 dimensions in jocobians[0]
But when I run the program, the report is like below:
Solver Summary (v 1.12.0-eigen-(3.2.0)-lapack-suitesparse-(4.2.1)-openmp)
Original Reduced
Parameter blocks 1 1
Parameters 3 3
Residual blocks 1 1
Residual 1 1
Minimizer TRUST_REGION
Dense linear algebra library EIGEN
Trust region strategy LEVENBERG_MARQUARDT
Given Used
Linear solver DENSE_QR DENSE_QR
Threads 1 1
Linear solver threads 1 1
Linear solver ordering AUTOMATIC 1
Cost:
Initial 8.569800e+04
Final 8.569800e+04
Change 0.000000e+00
Minimizer iterations 1
Successful steps 1
Unsuccessful steps 0
Time (in seconds):
Preprocessor 0.0001
Residual evaluation 0.0000
Jacobian evaluation 0.0050
Linear solver 0.0000
Minimizer 0.0051
Postprocessor 0.0000
Total 0.0052
Termination: CONVERGENCE (Gradient tolerance reached. Gradient max norm: 0.000000e+00 <= 1.000000e-10)
Since I have set the jacobians, how can it say that the gradient norm is so small?

Two things.
1. You cannot unconditionally set the Jacobian, you need to check if the solver is actually asking for and the pointers are non-null.
2. There is something wrong with your Jacobian eval, because as far as Ceres can tell it is seeing a zero gradient. Simple thing to check would be to dump out the Jacobian and Jacobian'residual from the CostFunction before returning.
for example are you sure size != 0?

Related

Why does this 1-dimensional Perlin Noise Generator Return Values > 1?

For educational purposes I want to implement the 1-dimensional Perlin Noise algorithm in Kotlin. I familiarized myself with the algorithm here and here.
I think I understood the basic concept, however my implementation can return values greater than 1. I expect the result of the call perlin(x) to be in the range 0 to 1. I can't figure out where I'm mistaken, so maybe someone can point me in the right direction. For simplicity I use simple linear interpolation instead of smoothstep or other advanced techniques for now.
class PerlinNoiseGenerator(seed: Int, private val boundary: Int = 10) {
private var random = Random(seed)
private val noise = DoubleArray(boundary) {
random.nextDouble()
}
fun perlin(x: Double, persistence: Double = 0.5, numberOfOctaves: Int = 8): Double {
var total = 0.0
for (i in 0 until numberOfOctaves) {
val amplitude = persistence.pow(i) // height of the crests
val frequency = 2.0.pow(i) // number of crests per unit distance
val octave = amplitude * noise(x * frequency)
total += octave
}
return total
}
private fun noise(t: Double): Double {
val x = t.toInt()
val x0 = x % boundary
val x1 = if (x0 == boundary - 1) 0 else x0 + 1
val between = t - x
val y0 = noise[x0]
val y1 = noise[x1]
return lerp(y0, y1, between)
}
private fun lerp(a: Double, b: Double, alpha: Double): Double {
return a + alpha * (b - a)
}
}
For example if you would use these random generated noises
private val noise = doubleArrayOf(0.77, 0.02, 0.63, 0.74, 0.49, 0.22, 0.19, 0.76, 0.16, 0.08)
You would end up with an image like this:
where the green line is the calculated Perlin Noise of 8 octaves with a persistence of 0.5. As you can see the sum of all octaves at x=0 for example is greater than 1. (The blue line being the first octave noise(x) and the orange one being the second octave 0.5 * noise(2x)).
What am I doing wrong?
Thanks in advance.
Note: I'm aware that the Simplex Noise algorithm is the successor of Perlin Noise, however for educational purposes I want to implement Perlin Noise first. I'm also aware that my boundary should be set to something in the magnitude of 256 but for simplicity I just used 10 for now.
I've been digging around and found this article which introduces a value to normalize the results returned by Perlin(x). Essentially the amplitudes are summed up and the total is divided by this value. This seems to make sense since we could have "bad luck" and have a y-value of 1.0 in the first octave, followed by a 0.5 in the next, etc. So dividing by the sum of the amplitudes (1.5 in this case with 2 octaves) seems reasonable to keep the values in the range 0 - 1.
However, I'm unsure if this is the preferred way since none of the other resource uses this technique.
The modified code would look like this:
fun perlin(x: Double, persistence: Double = 0.5, numberOfOctaves: Int = 8): Double {
var total = 0.0
var amplitudeSum = 0.0 //used for normalizing results to 0.0 - 1.0
for (i in 0 until numberOfOctaves) {
val amplitude = persistence.pow(i) // height of the crests
val frequency = 2.0.pow(i) // frequency (number of crests per unit distance) doubles per octave
val octave = amplitude * noise(x * frequency)
total += octave
amplitudeSum += amplitude
}
return total / amplitudeSum
}

Different FFT results from Matlab fft and Objective-c fft

Here is my code in matlab:
x = [1 2 3 4];
result = fft(x);
a = real(result);
b = imag(result);
Result from matlab:
a = [10,-2,-2,-2]
b = [ 0, 2, 0,-2]
And my runnable code in objective-c:
int length = 4;
float* x = (float *)malloc(sizeof(float) * length);
x[0] = 1;
x[1] = 2;
x[2] = 3;
x[3] = 4;
// Setup the length
vDSP_Length log2n = log2f(length);
// Calculate the weights array. This is a one-off operation.
FFTSetup fftSetup = vDSP_create_fftsetup(log2n, FFT_RADIX2);
// For an FFT, numSamples must be a power of 2, i.e. is always even
int nOver2 = length/2;
// Define complex buffer
COMPLEX_SPLIT A;
A.realp = (float *) malloc(nOver2*sizeof(float));
A.imagp = (float *) malloc(nOver2*sizeof(float));
// Generate a split complex vector from the sample data
vDSP_ctoz((COMPLEX*)x, 2, &A, 1, nOver2);
// Perform a forward FFT using fftSetup and A
vDSP_fft_zrip(fftSetup, &A, 1, log2n, FFT_FORWARD);
//Take the fft and scale appropriately
Float32 mFFTNormFactor = 0.5;
vDSP_vsmul(A.realp, 1, &mFFTNormFactor, A.realp, 1, nOver2);
vDSP_vsmul(A.imagp, 1, &mFFTNormFactor, A.imagp, 1, nOver2);
printf("After FFT: \n");
printf("%.2f | %.2f \n",A.realp[0], 0.0);
for (int i = 1; i< nOver2; i++) {
printf("%.2f | %.2f \n",A.realp[i], A.imagp[i]);
}
printf("%.2f | %.2f \n",A.imagp[0], 0.0);
The output from objective c:
After FFT:
10.0 | 0.0
-2.0 | 2.0
The results are so close. I wonder where is the rest ? I know missed something but don't know what is it.
Updated: I found another answer here . I updated the output
After FFT:
10.0 | 0.0
-2.0 | 2.0
-2.0 | 0.0
but even that there's still 1 element missing -2.0 | -2.0
Performing a FFT delivers a right hand spectrum and a left hand spectrum.
If you have N samples the frequencies you will return are:
( -f(N/2), -f(N/2-1), ... -f(1), f(0), f(1), f(2), ..., f(N/2-1) )
If A(f(i)) is the complex amplitude A of the frequency component f(i) the following relation is true:
Real{A(f(i)} = Real{A(-f(i))} and Imag{A(f(i)} = -Imag{A(-f(i))}
This means, the information of the right hand spectrum and the left hand spectrum is the same. However, the sign of the imaginary part is different.
Matlab returns the frequency in a different order.
Matlab order is:
( f(0), f(1), f(2), ..., f(N/2-1) -f(N/2), -f(N/2-1), ... -f(1), )
To get the upper order use the Matlab function fftshift().
In the case of 4 Samples you have got in Matlab:
a = [10,-2,-2,-2]
b = [ 0, 2, 0,-2]
This means:
A(f(0)) = 10 (DC value)
A(f(1)) = -2 + 2i (first frequency component of the right hand spectrum)
A(-f(2) = -2 ( second frequency component of the left hand spectrum)
A(-f(1) = -2 - 2i ( first frequency component of the left hand spectrum)
I do not understand your objective-C code.
However, it seems to me that the program returns the right hand spectrum only.
So anything is perfect.

Binary Search, when should I increment high or low?

I am having difficult to understand how to increment low or high.
For instance, this is a question from leetcode:
Implement int sqrt(int x).
My code:
class Solution {
public:
int mySqrt(int x) {
if (x<=0) return 0;
int low=1, high=x, mid=0;
while (low<=high){ // should I do low<high?
mid=low+(high-low)/2;
if (x/mid==mid) return mid;
if (x/mid>mid) low= mid+1; //can I just do low=mid?
else high=mid-1; // can I do high =mid?
}
return high; //after breaking the loop, should I return high or low?
}
};
You see, after a condition is fufill, I don't know whether I should set low=mid OR low=mid+1. Why mid+1?
In general, I am having trouble to see whether I should increment low from mid point or not. I am also having trouble when should I include low <= high or low < high in the while loop.
Your algo is not binary search.
Also, it doesn't work.
Take example x = 5
Initial:
low = 1, high = 5
Iter 1:
mid = 3
5/3 = 1 so high = 4
Iter 2:
mid = 2.5 => 2 (because int)
5/2 = 2 (because int)
<returns 2>
For perfect square inputs, your algo will give correct results only through mid not high or low.
BTW you need to increase mid if x/mid > mid and you need to decrease it otherwise. Your method of increasing and decreasing mid is incrementing low, or decrementing high respectively.
This is OK, but this doesn't yield a binary search. Your high would be walking through all the integers from x to (2*sqrt - 1).
Please follow #sinsuren comment to a far better solution
This is Babylonian method for square root:
/*Returns the square root of n.*/
float squareRoot(float n)
{
/*We are using n itself as initial approximation
This can definitely be improved */
float x = n;
float y = 1;
float e = 0.000001; /* e decides the accuracy level*/
while(x - y > e)
{
x = (x + y)/2;
y = n/x;
}
return x;
}
For more understanding you can always follow this link

Collision Angle Detection

I have some questions regarding collision angles. I am trying to code physics for a game and I do not want to use any third party library, actually I want to code each and every thing by myself. I know how to detect collisions between two spheres but I can't figure out, how to find the angle of collision/repulsion between the two spherical objects. I've tried reversing the direction of the objects, but no luck. It would be very nice if you link me to an interesting .pdf file teaching physics programming.
There's a lot of ways to deal with collision
Impulsion
To model a impulsion, you can directly act on the speed of each objects, using the law of reflection, you can "reflect" each speed using the "normal of the impact"
so : v1 = v1 - 2 x ( v1 . n2 ) x n2
and v2 = v2 - 2 x ( v2 . n1 ) x n1
v1 and v2 speeds of sphere s1 and s2
n1 and n2 normal at collision point
Penalty
Here, we have 2 object interpenetrating, and we model the fact that they tend to not interpenetrate anymore, so you create a force that is proportional to the penetration using a spring force
I didn't speak about all the ways, but this are the two simplest I know
the angle between two objects in the 2D or 3D coordinate space can be found by
A * B = |A||B|cosɵ
Both A and B are vectors and ɵ is the angle between both vectors.
the below class can be used to solve basic Vector calculations in games
class 3Dvector
{
private:
float x, y, z;
public:
// purpose: Our constructor
// input: ex- our vector's i component
// why- our vector's j component
// zee- our vector's k component
// output: no explicit output
3Dvector(float ex = 0, float why = 0, float zee = 0)
{
x = ex; y = why; z = zee;
}
// purpose: Our destructor
// input: none
// output: none
~3Dvector() { }
// purpose: calculate the magnitude of our invoking vector
// input: no explicit input
// output: the magnitude of our invoking object
float getMagnitude()
{
return sqrtf(x * x + y * y + z * z);
}
// purpose: multiply our vector by a scalar value
// input: num - the scalar value being multiplied
// output: our newly created vector
3Dvector operator*(float num) const
{
return 3Dvector(x * num, y * num, z * num);
}
// purpose: multiply our vector by a scalar value
// input: num - the scalar value being multiplied
// vec - the vector we are multiplying to
// output: our newly created vector
friend 3Dvector operator*(float num, const 3Dvector &vec)
{
return 3Dvector(vec.x * num, vec.y * num, vec.z * num);
}
// purpose: Adding two vectors
// input: vec - the vector being added to our invoking object
// output: our newly created sum of the two vectors
3Dvector operator+(const 3Dvector &vec) const
{
return 3Dvector(x + vec.x, y + vec.y, z + vec.z);
}
// purpose: Subtracting two vectors
// input: vec - the vector being subtracted from our invoking object
// output: our newly created difference of the two vectors
3Dvector operator-(const 3Dvector &vec) const
{
return 3Dvector(x - vec.x, y - vec.y, z - vec.z);
}
// purpose: Normalize our invoking vector *this changes our vector*
// input: no explicit input
// output: none
void normalize3Dvector(void)
{
float mag = sqrtf(x * x + y * y + z * z);
x /= mag; y /= mag; z /= mag
}
// purpose: Dot Product two vectors
// input: vec - the vector being dotted with our invoking object
// output: the dot product of the two vectors
float dot3Dvector(const 3Dvector &vec) const
{
return x * vec.x + y * vec.y + z * vec.z;
}
// purpose: Cross product two vectors
// input: vec- the vector being crossed with our invoking object
// output: our newly created resultant vector
3Dvector cross3Dvector(const 3Dvector &vec) const
{
return 3Dvector( y * vec.z – z * vec.y,
z * vec.x – x * vec.z,
x * vec.y – y * vec.x);
}
};
I shouldn't be answering my own question but I found what I needed, I guess. It may help other people too. I was just fingering the wikipedia's physics section and I got this.
This link solves my question
The angle in a cartesian system can be found this way:
arctan((Ya-Yb)/(Xa-Xb))
Because this is a retangle triangle where you know the catets (diferences of heights and widths). This will calc the tangent. So the arctan will calc the angle thats have this tangent.
I hope I was helpful.

Discrete Wavelet Transform on images and watermark embedding in LL band coefficients, data is lost when IDWT-DWT is performed again?

I'm writing an image watermarking system to hide a watermark in an image's low frequency band by transforming the image's luminance channel with a Discrete Wavelet Transform, then modifying coefficients in the LL band of the DWT output. I then do an Inverse DWT and rebuild my image.
The problem I'm having is when I modify coefficients in the DWT output, then inverse-DWT, and then DWT again, the modified coefficients are radically different.
For example, one of the output coefficients in the LL band of the 2-scale DWT was -0.10704, I modified this coefficient to be 16.89, then performed the IDWT on my data. I then took the output of the IDWT and performed a DWT on it again, and my coefficient which was modified to be 16.89 became 0.022.
I'm fairly certain that the DWT and IDWT code is correct because I've tested it against other libraries and the output from each transform matches when the filter coefficients and other parameters are the same. (Within what can be expected due to rounding error)
The main problem I have is that I perhaps don't understand the DWT all that well, I thought DWT and IDWT were supposed to be reasonably lossless (Aside from rounding error and such), yet this doesn't seem to be the case here.
I'm hoping someone more familiar with the transform can point me at a possible issue, is it possible that because the coefficients in my other subbands (LH, HL, HH) for that position are insignificant I'm losing data? If so, how can I determine which coefficients this may happen to?
My embedding function is below, coefficients are chosen in the LL band, "strong" is determined to be true if the absolute value of the LH, HH, or HL band for the selected location is larger than the mean value of the corresponding subband.
//If this evaluates to true, then the texture is considered strong.
if ((Math.Abs(LH[i][w]) >= LHmean) || (Math.Abs(HL[i][w]) >= HLmean) || (Math.Abs(HH[i][w]) >= HHmean))
static double MarkCoeff(int index, double coeff,bool strong)
{
int q1 = 16;
int q2 = 8;
int quantizestep = 0;
byte watermarkbit = binaryWM[index];
if(strong)
quantizestep = q1;
else
quantizestep = q2;
coeff /= (double)quantizestep;
double coeffdiff = 0;
if(coeff > 0.0)
coeffdiff = coeff - (int)coeff;
else
coeffdiff = coeff + (int)coeff;
if (1 == ((int)coeff % 2))
{
//odd
if (watermarkbit == 0)
{
if (Math.Abs(coeffdiff) > 0.5)
coeff += 1.0;
else
coeff -= 1.0;
}
}
else
{
//even
if (watermarkbit == 1)
{
if (Math.Abs(coeffdiff) > 0.5)
coeff += 1.0;
else
coeff -= 1.0;
}
}
coeff *= (double)quantizestep;
return coeff;
}