I've found out that the results of the SVDecomp function in Java are very different from the results of WolframAlpha.
The input matrix is excactly the same for OpenCV and WolframAlpha
{{0.2229632566816983, 18.15370964847313, 4.87085706173828},
{-14.31728552253419, 2.642676839378287, -33.69501515553716},
{-2.982323803144884, 33.70091859922499, 0.8997452211463326}}
Here are the results from WolframAlpha:
U = (-0.441818862735368 | 0.214800119324567 | -0.871009185525260
-0.245069575462508 | -0.962880608842737 | -0.113145200062862
-0.862981457340684 | 0.163468167704881 | 0.478059789601005)
W = (38.5925763913943 | 0 | 0
0 | 36.8337256561100 | 0
0 | 0 | 3.76859638821616×10^-10)
V = (0.155053443270976 | 0.362336795687042 | 0.919059560758203
-0.978207790691182 | 0.186347267503429 | 0.0915653543928191
0.138086740713550 | 0.913228745925823 | -0.383334461865688)
And here is what OpenCV produces when using SCDecomp:
U: [0.4418188627353685, 0.2148001193245664, -0.8710091855252606;
0.2450695754625076, -0.9628806088427376, -0.113145200062862;
0.8629814573406845, 0.1634681677048805, 0.4780597896010051]
W: [38.59257639139431; 36.83372565611004; 3.768597946996713e-10]
VT:[-0.155053443270976, 0.3623367956870423, 0.9190595607582029;
0.9782077906911818, 0.1863472675034285, 0.09156535439281914;
-0.1380867407135498, 0.9132287459258235, -0.3833344618656882]
To mention: W in OpenCV is not a matrix, as well as the sign of the values are sometimes different.
Is this a bug? Here is my SourceCode
Core.SVDecomp(E, w, u, vt);
I don't think the result are that different:
Both U matrices contain the same vector with the 1st one (1st column of each matrix) being the opposite of the other (no problem here just a sign alteration)
W is the same but in the first case is returned as diagonal matrix and in the second as vector (only the main diagonal is returned).
The V matrices are the same case as the U ones (the first vector is the opposite).
So the results are the same.
Related
Below is a function which takes int and return int. Within the function I call the function itself and if i==1, I want to go out of my function.
Basically I'm trying to calculate factorial in recursive manner.
Code Snippet
static int factorial(int i){
result = result * i;
if(i==1){
return 0;
}
factorial(i-1);
return 1;
}
Note - result is an global int variable and is initialize to 1.
Why this function returns 1 instead of 0.
[Note when i==1 then with return statement the pointer should come out of the function]
Please don't post better algorithm for factorial, I'm looking for - why this code is behaving a bit different.
Your code doesn't even compile as result isn't defined.
Then, the method could return either 0 or 1, nothing else regarding the return you wrote, so you can't expect to get real values.
Then the real algorithm
for 0 or 1, return 1
else return the value multiplied by the factorial(previous)
static int factorial(int i) {
if (i <= 1) { // for 0 or 1
return 1;
}
return i * factorial(i - 1);
}
example calling factorial(3):
int i = factorial(3);
+--------------------------------------------------+
|result = result * 3; |
|if (i==1) { |
| // not executed |
|} |
|factorial(2); |
| +-------------------------------------------+ |
| |result = result * 2; | |
| |if (i==1) { | |
| | // not executed | |
| |} | |
| |factorial(1); | |
| | +---------------------------------+ | |
| | |result = result * 1; | | |
| | |if (i==1) { | | |
| | | return 0; | | |
| | |// nothing more in factorial(1) | | |
| | +---------------------------------+ | |
| |// factorial(1) returned 0 (value not used)| |
| |return 1; // factorial(2) | |
| +-------------------------------------------+ |
|// factorial(2) returned 1 (value not used) |
|return 1; // factorial(3) |
+--------------------------------------------------+
i = 1; // the value returned by last call
factorial(3) returns 1! recursion was terminated by return 0, but that value is not being used
Zero would have been returned if the last two lines were joined to return factorial(i-1);
only factorial(1) will return 0, e.g. int i = factorial(1)
Because u are not returning 0. Your function will always return 1 which is the returned value of the first call. All the other recursive function calls are being made but not being used to return by the parent function. For example if you call factorial(5) then all the recurring calls (from 4 to 1) would execute and process the "result" variable but you will only get the returned value of factorial(5) which is always going to be 1.
The fundamental problem with your code is that it is confused about how it wants to return data.
You have a result global variable which is supposed to be how this function 'communicates' the answer, but it also has a return value. They sound quite different (one is a variable, one is a language construct), but they are used for the same purpose here. Half the time you return, half the time you set result, and this leads to your code having the effects you are observing.
The solution is to pick a side. Either use only result - update the method to have a void return value, and do not use the return x; statement (only return;). Alternatively, get rid of result entirely, and communicate using return.
if(i==1){
return 0;
}
Take this line and compare to the very next one:
factorial(i-1);
This line calls the factorial function and throws out whatever it returned because you don't assign it anywhere. That is why you can't observe that 0 you are returning: Because you ignore it.
It looks to me like you think that return 0; somehow sets result, or that result holds 'whatever the function returned' but this isn't true. They are separate things.
Need: To filter out data in list - 1 based on the values present in list - 2 with multiple criteria i.e. combination of Date & Order Number
Issue: Able to filter based on 1 criteria. But when I try adding another filter condition it treats it as 2 separate & not as combination. Unable to figure out how to make it as a combination.
Hope issue faced is clear.
Research: I referred to my earlier query on similar need - Link1 . Also checked - Link2
List 1: (All Orders)
[Date | OrderNumber | Time | Company | Rate ]
[2014-10-01 | 12345 | 10:00:01 | CompA | 1000]
[2015-03-01 | 23456 | 08:00:01 | CompA | 2200]
[2016-08-01 | 34567 | 09:00:01 | CompA | 3300]
[2017-09-01 | 12345 | 11:00:01 | CompA | 4400]
[2017-09-01 | 98765 | 12:00:01 | CompA | 7400]
List 2: (Completed Orders)
[Date | OrderNumber | Time]
[2014-10-01 | 12345 | 10:00:01]
[2015-03-01 | 23456 | 08:00:01]
[2016-08-01 | 34567 | 09:00:01]
[2017-09-01 | 98765 | 12:00:01]
Expected O/p after filter :
[Date | OrderNumber | Time | Company | Rate]
[2017-09-01 | 12345 | 11:00:01 | CompA | 4400]
Code:
// Data extracted from MySQL database
// List 1: All Orders
List<ModelAllOrders> listOrders = getDataFromDatabase.getTable1();
// List 2: Completed Orders
List<ModelCompletedOrders> listCompletedOrders = getDataFromDatabase.getTable2();
// Filter with 1 criteria works
Set<Integer> setOrderNumbers = listCompletedOrders.stream().map(ModelCompletedOrders::getOrderNumber).collect(Collectors.toSet());
listOrders = listOrders.stream().filter(p -> !setOrderNumbers.contains(p.getOrderNumber()).collect(Collectors.toList());
// Below not working as expected when trying to combinational filter
Set<LocalDate> setDates = listCompletedOrders.stream().map(ModelCompletedOrders::getDate).collect(Collectors.toSet());
listOrders = listOrders.stream().filter(p -> !setDates.contains(p.getDate()) && !setOrderNumbers.contains(p.getOrderNumber()))
.collect(Collectors.toList());
You've asked for logic that will do this:
The combination of Date & Order Number is unique. I need to check if that unique combination is present in List-2, if yes then filter out, if not then output should contain that row.
Stream::filter() will return a subset of the stream where the filter predicate returns true (i.e. it filters out those objects in the stream where the predicate is false).
listOrders = listOrders.stream().filter(p -> !setDates.contains(p.getDate()) && !setOrderNumbers.contains(p.getOrderNumber()))
.collect(Collectors.toList());
Your code expression here says "show me orders where the order's date does not appear in the list of prior orders AND where the order's order number does not appear in the list of prior orders". Your logical expression is wrong (you're getting confused between what in electronics would be called positive vs negative logic).
You want either:
listOrders = listOrders.stream().filter(p -> !(setDates.contains(p.getDate()) && setOrderNumbers.contains(p.getOrderNumber())))
.collect(Collectors.toList());
"show me orders where both the order's date and order's id are not
present in the list of prior orders"
or:
listOrders = listOrders.stream().filter(p -> !setDates.contains(p.getDate()) || !setOrderNumbers.contains(p.getOrderNumber()))
.collect(Collectors.toList());
"show me orders where either the order's date has not been seen before
OR the order's id has not been seen before"
public static void reversePrint(int[] numbers){
if(numbers.length == 0) //Base case
return;
int[] a = new int[numbers.length-1];
for(int i = 0; i < numbers.length-1;i++)
a[i] = numbers[i+1];
reversePrint(a);
System.out.println(numbers[0]);
}
public static void main(String[] args){
int[] array = new int[]{5,1,34,12,7};
reversePrint(array);
}
Output:
7
12
34
1
5
Everything is pretty straightforward, have a function called reversePrint. When you pass those numbers to the function reversePrint, it takes the first value out, (in this case '5') and then it calls reversePrint again,now with the smaller list.
This Continues until finally we're left with no more numbers, and begins to print them out.
My confusion is in line '10', if the list of numbers is getting less and less by removing the first number each time, how does calling 'System.out.println(numbers[0]);' retrieve numbers that have been removed from the list, and doing so in reverse order?
Here's a scheme to understand the stack of calls in this recursion:
reversePrint([5,1,34,12,7]) {
reversePrint([1,34,12,7]) { // <-- this list IS A COPY, it just ignores the first number
reversePrint([34,12,7]) {
reversePrint([12,7]) {
reversePrint([7]) {
reversePrint([]);
print(7); // <-- this is the first number of the current list
};
print(12);
};
print(34);
};
print(1);
};
print(5);
};
As you can see, the System.out.println(numbers[0]) is called AFTER propagating the recursion. Note that a new array is created in each call, you don't lose the first number.
First, you don't actually remove numbers: you copy them from numbers to a skipping the one in position 0. That System.out.println prints from numbers, so the integer at index 0 will still be the same.
Second, the System.out.println statement is after the recursive call, so it will be executed after that call returns. So basically, the first System.out.println that will execute will be the one in the last call:
for ...
reversePrint
|
| for ...
| reversePrint
| |
| | for ...
| | reversePrint
| | |
| | | for ...
| | | reversePrint
| | | |
| | | | for ...
| | | | reversePrint
| | | | |
| | | | | return
| | | | |
| | | | System.out.println
| | | |
| | | System.out.println
| | |
| | System.out.println
| |
| System.out.println
|
System.out.println
That's an exceptionally ineffective implementation of
Arrays.asList(5, 1, 34, 12, 7).reverse().forEach(System.out::println)
But to answer your question, the reversePrint creates a new array with the first item removed from the array, then prints out the first of the original. The second call will receive [1, 34, 12, 7] because the first has removed the 5, so it will print out the 1.
how does calling 'System.out.println(numbers[0]);' retrieve numbers that have been removed from the list, and doing so in reverse order?
No numbers have been removed from any array in this code. Each recursive call creates a new array and copies to it all the elements of the current array except of the first element.
Therefore the array passed to the i'th call to reversePrint() contains the last n-i+1 elements of the original array.
The recursion ends when reversePrint() is called for an empty array. When the last recursive call returns, the next to last call prints numbers[0], which contains the last element of the original array. Then the previous reversePrint() prints numbers[0], which contains the next to last element of the original array, and so on...
These are the recursive calls:
reversePrint({5,1,34,12,7})
reversePrint({1,34,12,7})
reversePrint({34,12,7})
reversePrint({12,7})
reversePrint({7})
reversePrint({})
Now, after each of them returns, numbers[0] is printed, so you get
7
12
34
1
5
Perhaps doing it the classic way (rather than making a copy of the array as you do) it would be clearer what is happening.
// Private version to pass the offset which increases on each call.
private static void reversePrint(int[] numbers, int from){
// Base case - stop at end of array.
if(numbers.length > from) {
// Print everything else first.
reversePrint(numbers, from+1);
// Then the one I am at.
System.out.println(numbers[from]);
}
}
public static void reversePrint(int[] numbers){
reversePrint(numbers, 0);
}
public void test() throws Exception {
System.out.println("Hello world!");
int[] array = new int[]{5,1,34,12,7};
reversePrint(array);
}
This question already has answers here:
Are arrays passed by value or passed by reference in Java? [duplicate]
(7 answers)
Closed 6 years ago.
Background
I am making an array tools class for adding Python functionality to a Java array, and I came across this problem. This is obviously a simplified, more universal version.
Question
In this example:
public class ArrayTest
{
public static void main(String[] args)
{
// initial setup
int[] given = {1, 2, 3, 4, 5};
// change array
int[] changed = adjust(given);
// these end up being the same...
System.out.println(Arrays.toString(changed));
System.out.println(Arrays.toString(given));
}
private static int[] adjust(int[] a)
{
for (int i = 0; i < a.length; i++)
{
a[i]++;
}
return a;
}
}
...why is changed and given the same thing?
Disclaimer
I am guessing that this has been asked before, but I couldn't find an answer, so I apologize for that.
When you do
int[] given = {1, 2, 3, 4, 5};
given's value is called an object reference. It's a value telling the JVM where that array is, elsewhere in memory. given doesn't contain the array (like it would an int), it contains a reference to the array (e.g., like an address). E.g.:
+−−−−−−−−−+
[given:Ref88465]−−−−>| (array) |
+−−−−−−−−−+
| 0: 1 |
| 1: 2 |
| 2: 3 |
| 3: 4 |
| 4: 5 |
+−−−−−−−−−+
When you call adjust(given), you're passing a copy of the value of given into adjust. That copy still points to the same place in memory. E.g., during the call to adjust, we have two copies of that object reference, both pointing to the same single array:
+−−−−−−−−−+
[given:Ref88465]−−−−>| (array) |
/ +−−−−−−−−−+
| | 0: 1 |
| | 1: 2 |
| | 2: 3 |
| | 3: 4 |
| | 4: 5 |
| +−−−−−−−−−+
[a:Ref88465]−−−−−−+
When you change the contents of the array, you're modifying the state of array. When adjust returns and you assign the result to changed, you have:
+−−−−−−−−−+
[given:Ref88465]−−−−−>| (array) |
/ +−−−−−−−−−+
| | 0: 2 |
| | 1: 3 |
| | 2: 4 |
| | 3: 5 |
| | 4: 6 |
| +−−−−−−−−−+
[changed:Ref88465]−+
If you want a copy of the array with the changes, you'll need to make a copy of it, for instance via arraycopy. Both copying and changing-in-place are used in practice, depending on the use case.
what you are doing is sending the address of your array to your method , so what was changed is your original array and you just return it( the address of your array) so any change you have done on that array(memory) will be reflected in both variables as both are pointing to the same memory location
1 public class TestWin{
2 public static void main(String[] args){
3 int n;
4 hexagon[][] board;
5
6 n = 4;
7 board = new hexagon[n][n];
8 board[0][0].value = 'R';
Hi. javac doesn't like what I did on line 8. Does anyone know why?
It's been a while since I've so much as looked at Java, but have you tried doing this first?
board[0][0] = new hexagon(); // or whatever its constructor is
Spot on kwatford. All you have done with line 7 is to tell java to create space for n*n Hexagon objects in a 2 dimensional array.
You will still need to call new for each of these Hexagons
Essentially, you need to replace line 7 with something like:
board = new Hexagon[n][n];
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
board[i][j] = new Hexagon();
Short Answer:
As kwatford said what you need to do is this:
board[0][0] = new hexagon(); // or whatever its constructor is
Longer Explanation:
Just to expand further. Your 2D array is; an array of pointers (or references in Java). This is what one row of the array will look like immediately after this call board = new hexagon[n][n];:
0 1 2 3 4 5 // column index, row index = 0
-------------------------------------------
| | | | | | | | | | // value
--- | ----- | ----- | ---------------------
| | | ...
| | |
| | |
| | |
| | v
| | Null
| v
| Null
v
Null (This means that it points to nothing)
You tried:
board[0][0].value = 'R';
which is the same as this:
null.value = 'R';
You have initialized your array using this line:
board = new Hexagon[n][n];
But you still need to initialize the elements in your array. This would initialize the first three:
board[0][0] = new hexagon(); // or whatever its constructor is
board[1][0] = new hexagon(); // or whatever its constructor is
board[2][0] = new hexagon(); // or whatever its constructor is
Which would result in an array that looks like this:
0 1 2 3 4 5 // column index, row index = 0
-------------------------------------------
| | | | | | | | | | // value
--- | ----- | ----- | ---------------------
| | |
| | |
| | |
| | |
| | v
| | An instance of type Hexigoon (what you get when you type new Hexigon)
| v
| An instance of type Hexigon (what you get when you type new Hexigon)
v
An instance of type Hexigon (what you get when you type new Hexigon)
I remember banging my head on the table with this exact problem two years ago. I love stackoverflow
To expand on what kwatford said, initializing an array in java gives you nulls if the array type is an object. If you had a raw array, such as an array of doubles, you would start with 0 as the entry for each element of the array.