I'm doing some basic computation using the Apache Commons Library, and I have a 2x2 symmetric RealMatrix for which I need to compute the EigenDecomposition. The matrix is as follows:
{{10.387035702893005, 0.14862451664049367},
{0.14862451664049442, -5.1952457826500815}}
The top right and bottom left elements, of type double, are supposed to be identical, and you'll notice that they almost are. When I pass the matrix to a new instance of EigenDecomposition, however, I'll get an exception. isSymmetric() evaluates false, and because the constructor passes in 'true' as a parameter, the isSymmetric() method raises an exception. I basically need to bypass this check. What are my options? Thanks!
public EigenDecomposition(final RealMatrix matrix,
final double splitTolerance) {
if (isSymmetric(matrix, true)) {
transformToTridiagonal(matrix);
findEigenVectors(transformer.getQ().getData());
}
}
N.B. The split tolerance parameter, which one might think specifies a tolerance level, is merely a dummy parameter.
The problem seems to be a numerical error - the values are almost identical, but not exactly. A quick and dirty solution could be:
Check if the two values equal each other using the condition: Math.abs(matrix[0][1] - matrix[1][0]) < DELTA. where DELTA is your tolerance factor (what is the maximum you can tolerate so the matrix will be considered symetric).
If it is - assign matrix[0][1] = matrix[1][0]
It is easy to see that a matrix that suffices the condition should now be symetric by definition.
Can you override isSymmetric and then get the second paramter to be ignored. YOu could then call your own isSymmetric method
For example
#override
public boolean isSymmetric(RealMatrix m, Boolean b) {
return _isSymmetric(m);
}
where _isSymmetric(m) is your own implementation. You could then compare the double values in any way you see fit. I would recommend using delta rather than a straight == as double values are very rarely exactly equaly but usually are equal enough ;)
If the two values are supposed to be equal, can you just copy one over the top of the other?
matrix[0][1] = matrix[1][0];
Related
I wrote something like
#Override public int compareTo(Cuboid that) {
return -ComparisonChain.start()
.compare(this.d0, that.d0)
.compare(this.d1, that.d1)
.compare(this.d2, that.d2)
.result();
}
To reverse the order, I simply negated the result, but now I see it was wrong as the docs says
Ends this comparison chain and returns its result: a value having the
same sign as the first nonzero comparison result in the chain, or zero if
every result was zero.
So Integer.MIN_VALUE is an allowed return value and then the negation fails. In the source code, I can see that nothing but -1, 0, and +1 gets ever returned, but this isn't something I'd like to depend on.
Instead of the negation I could swap all the operands. Simple and ugly, but I'm curious if there's a better solution.
One option that may be more clear than reversing the compare arguments would be to compare each pair of arguments with the reverse of their natural ordering:
.compare(this.d0, that.d0, Ordering.natural().reverse())
I don't know if that's better (personally I don't like to involve floating point operations), but you could send it through Math#signum:
return -Math.signum( .... );
I'd probably just swap the operands.
Maybe this?
int temp = ComparisonChain.start()
.compare(this.d0, that.d0)
.compare(this.d1, that.d1)
.compare(this.d2, that.d2)
.result();
return temp == Integer.MIN_VALUE ? Integer.MAX_VALUE : -temp;
There's actually a signum function using no floating point, namely Integer#signum(int) and it's about 3.5 times faster then Math.signum with the cast to double.
Out of curiosity, the fastest solution is
return -((x&1) | (x>>1));
but only by about 10%.
What would be the simple way to implement equivalence class in Java? Is there any library for that purpose?
The bothering part is how to write an efficient and non-naive "equal" operator.
Let S = {x,y,z,w,h}. If we use a mapping x->1, y->1, z->1, w->2, h->2 for the equivalence class of S, one has to consider the mapping x->10, y->10, z->10, w->20, h->20 as the same equivalence class.
Naive "equal" operator can quickly become time-consuming when the cardinal of the set S becomes large.
What would be the simple way? Any idea?
[EDITED] To clarify, the specific problem can be formalized as follows:
Let S be a non-empty set. We denote by M a set of partial mappings from V to integers. It is relatively easy to show that the binary relation \sim defined below derives an equivalence relation on M.
For m1 and m2 two partial mappings of M, m1 \sim m2 if and only if,
for any a of V, m1(a) is defined if and only if m2(a) is defined
for any a,b of V, m1(a) and m1(b) are both defined to be the same
integer value 'z1' if and only if m2(a) and m2(b) are both defined
to the same integer value 'z2' (which may or may not differ from
'z1')
Example.
a->9,b->9,w->1 \sim a->10,b->10,w->0
But it is not correct to say
a->5 \sim b->9
Thanks.
From what I understand from your question you can find the greatest common divisor (Euclid's algorithm recursively) for a set once and map the quotients with that instead - if they're exactly equal with another set it's equal, else not. This will only work if the sets are equal in size and mappings.
If I understand you correct, you could apply vector normalization. A 3d vector for example is normalized to a length of 1 by dividing all of its components separately with the vectors length. If two normalized vector's components are equal, their original (non-normalized) vectors point in the same direction (which is what I think you define as 'equal')
x,y,z,w,h would in your case be a 5-dimensional vector. They belong to the same class when the show into the same direction, but may have an arbitrary length.
Aside: I assume that the set S is actually the set V in your definition.
I think Uli is on the right track, although I would not assume that Set(Set(E)).equals() is efficient for your purposes. (Sorry, I couldn't get the lt or gt symbols to come through)
The default implementation of Set(E).equals() is likely O(nlog n) or O(n^2). Set(E).equals() almost certainly involves sorting; O(nlog n) is as good as it gets. I suggest you look at radix sort. It's O(n*log n), but grows very slowly.
So I know I can convert a string to a hashcode simply by doing .hashCode(), but is there a way to convert (or use some other function if there is one out there) that will instead of returning an integer return a double between 0 and 1? I was thinking of just dividing the number by the maximum possible integer but wasn't sure if there was a better way.
*Edit (more information about why i'm trying to do this): i'm doing a mathematical operation, and i'm trying to group different objects to perform the same mathematical operation in their group but have a different parameter into the function. each member has a list of characteristics that "group" them... so i was thinking to put the characteristics into a string and then hashcode it and find their group value from that
You couldn't just divide by Integer.MAX_VALUE, as that wouldn't deal with negative numbers. You could use:
private static double INTEGER_RANGE = 1L << 32;
...
// First need to put it in the range [0, INTEGER_RANGE)
double doubleHash = ((long) text.hashCode() - Integer.MIN_VALUE) / INTEGER_RANGE;
That should be okay, as far as I'm aware... but I'm not going to make any claims about the distribution. There may well be a fairly simple way of using the 32 bits to make a unique double (per unique hash code) in the right range, but if you don't care too much about that, this will be simpler.
Dividing it should be ok, but you might loose some "precision" due to rounding problems, etc, that doubles might have.
In general a hash is used to identify something trying to assure it'll be unique, loosing precision might have problems in that.
You could write your own String.hashCodeDouble() returning the desired number, perhaps using a common hash algorithm (let's say, MD5) and adapting it to your required response range.
Example: do the MD5 of the String to get a hash, then simply put a 0. in front of it...
Remember that the .hashCode() is used in lots of functions in Java, you can't simply overwrite it.
This smells bad but might do what you want:
Integer iHash = "123".hashCode();
String sHash = "0."+iHash;
Double dHash = Double.valueOf(sHash);
Every time I need to implement a comparator, I get stuck trying to remember when I should return -1 and when 1, and I have to look it up.
I mean, obviously -1 is less, so it implies that first is less than second. But whenever I say that to myself, I get that nagging "are you sure?" feeling. I suspect part of my confusion comes from implementing it the other way around whenever I need a descending sort.
What do you use to remember which is which?
I use this simple "substraction" mnemonic:
first - second
So, if first is "less" than second you'll get negative result, otherwise - positive or zero if they are equal.
comparator.compare(a, b) < 0 <==> a < b
I am not sure what you mean by mnemonic. However, I have had a very similar cognitive dissonance.
I am very visual, so I use the number line (the one I was taught in grade school). I just visualize the negative numbers as "left", 0 as "center" and positive numbers as "right". That the corresponds to the truth: -1 < 0 < 1
I remember the base integer case (pseudocode):
int comparator(int a, int b) {
return a-b;
}
So if we give in a small a and a large b which is the first < last we get a negative result.
I have a more visual memory, so remembering the "structure" of that function is easy and natural for me.
I used to always check the documentation when implementing Comparator and Comparable interfaces.
Question: Compare a and b
Lets first at look ascending order since the descending order will be just the inverse of whatever we do.
Question can be translated to given two numbers a and b, how would you put them on the number line?
if a < b, then we will put a on the negative side and b on the positive side.
else if a = b then we will put both at the center (at 0)
otherwise b will be on the negative side and a will be on the positive side.
Comparator Implementation:
Here you are comparing a to b.
#Override
public int compare(MyClass a, MyClass b) { //always good to rename your variables like this to be consistent
return a.f1 - b.f1;
}
Comparable Implementation:
Here you are comparing this to other.
#Override
public int compareTo(MyClass other) { // this is same as compare(this, other)
return this.f1 - o.f1;
}
Can anybody explain how this function works?
public int TestAdd(int a,int b) {
if(a <1)return b;
return(TestAdd((a&b)<<1,a^b));
}
Adding two matching set binary digits is equivalent to setting the next bit up: 1+1=2, and so on. So the function does that for all matching bits, then carries the unmatched ones over to another round. When no unmatched ones remain, it's done.
Since you can obviously test to see that it does indeed add two numbers, I assume you aren't understanding what those symbols are doing. Java's operators are described here:
http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html
And you can easily look up the definitions of "logical AND" and "bitwise exclusive OR" and how they apply to ints.
Here we using the concept of recursion, this function call itself as values-
1 bit left shift of binary(Due to carry while adding) addition of numbers and xor of numbers until the a become <1.
Thus it returns the addition of numbers.
You can debug the function by taking some values for better understanding.