I just ported my code from MATLAB to Java, and I need the eigen decomposition of a matrix, specifically I only need the first k values not the full decomposition.
However in JAMA, the eigen-decomposition class computes the full eigen decomposition. I tried to modify it, but it throws some errors. Is there another similar library?
In MATLAB, the function in question is eigs(k,A)
So it's just returning the array of all the eigenvalues. You want to return an array with just the first k values of the array. There are many ways to do this in Java. One is to convert the array to an ArrayList, get a subList of that list, and convert back to an array.
double[] mySubArray = new double[k];
for (int i=0; i < k; i++) {
subArray[i] = myFullArray[i];
}
By the way, this is the library he is referring to: http://math.nist.gov/javanumerics/jama/doc/
In the case you cannot find any existing codes, I guess you should refer to this thesis or maybe this paper.
Maybe you can try another package named EigenDecomposition in http://commons.apache.org/proper/commons-math/javadocs/api-3.6/org/apache/commons/math3/linear/EigenDecomposition.html, there are some methods like getImagEigenvalue(int i), you can get the i-th eigenvalue by this.
Related
Starting with Java 8 so need a bit of time to get used to it. It's a classical problem, I've an array of objects that I want to transform.
Before Java8 the ideal code would be (no null pointers):
P[] outputArray = new P[inputArray.length];
for (int i =0; i< inputArray.length; i++ )
{
outputArray [i] = inputArray[i].transformToP();
}
What is the best version in Java8 ?
Using the Stream API it's quite simple:
P[] outputArray = Arrays.stream(inputArray).map(e -> e.transformToP()).toArray(P[]::new);
Also method reference can be used (suppose that I is the type of input elements):
P[] outputArray = Arrays.stream(inputArray).map(I::transformToP).toArray(P[]::new);
Note that you may have problems if transformToP() method throws checked exceptions. In this case convert them to unchecked ones or consult this question.
Using a stream over an array is a fine technique as described in Tagir Valeev's answer. However, don't forget about Arrays.setAll. This is a handy shortcut for setting all the elements of an array based on index. To transform an array to a new array by some function, you could do this:
P[] outputArray = new P[inputArray.length];
Arrays.setAll(outputArray, i -> inputArray[i].transform());
You don't have to copy it into a new array. If you want to transform the array in-place, you could do this:
Arrays.setAll(array, i -> array[i].transform());
There is also a parallel variation parallelSetAll.
Under the covers this is just an IntStream.range over the indexes of the input array, but it's sometimes darned convenient for quick one-liners.
I'm not sure if I'm using the right nomenclature, so I'll try to make my question as specific as possible. That said, I imagine this problem comes up all the time, and there are probably several different ways to deal with it.
Let's say I have an array (vector) called main of 1000 random years between 1980 and 2000 and that I want to make 20 separate arrays (vectors) out of it. These arrays would be named array1980, array1981, etc., would also have length 1000 but would contain 1s where the index in the name was equal to the corresponding element in main and 0s elsewhere. In other words:
for(int i=0; i<1000; i++){
if(main[i]==1980){
array1980[i]=1;
} else {
array1980[i]=0;
}
Of course, I don't want to have to write twenty of these, so it'd be good if I could create new variable names inside a loop. The problem is that you can't generally assign variable names to expressions with operators, e.g.,
String("array"+ j)=... # returns an error
I'm currently using Matlab the most, but I can also do a little in Java, c++ and python, and I'm trying to get an idea for how people go about solving this problem in general. Ideally, I'd like to be able to manipulate the individual variables (or sub-arrays) in some way that the year remains in the variable name (or array index) to reduce the chance for error and to make things easier to deal with in general.
I'd appreciate any help.
boolean main[][] = new boolean[1000][20];
for (int i=0; i < 1000; i++) {
array[i][main[i]-1980] = true;
}
In many cases a map will be a good solution, but here you could use a 2-dim array of booleans, since the size is known before (0-20) and continuous, and numerable.
Some languages will initialize an array of booleans to false for every element, so you would just need to set the values to true, to which main[i] points.
since main[i] returns numbers from 1980 to 2000, 1980-main[i] will return 1980-1980=0 to 2000-1980=20. To find your values, you have to add 1980 to the second index, of course.
The general solution to this is to not create variables with dynamic names, but to instead create a map. Exactly how that's done will vary by language.
For Java, it's worth looking at the map section of the Sun collections tutorial for a start.
Don Roby's answer is correct, but i would like to complete it.
You can use maps for this purpose, and it would look something like this:
Map<Integer,ArrayList<Integer>> yearMap = new HashMap<Integer,ArrayList<Integer>>();
yearMap.put(1980,new ArrayList<Integer>());
for (int i = 0; i < 1000; i++){
yearMap.get(1980).add(0);
}
yearMap.get(1980).set(999,1);
System.out.println(yearMap.get(1980).get(999));
But there is probably a better way to solve the problem that you have. You should not ask how to use X to solve Y, but how to solve Y.
So, what is it, that you are trying to solve?
How can I convert Vector<double[]> to double[][] in java ?
You can convert a Vector to an array by Vector.toArray():
double[][] array = vector.toArray(new double[0][]);
This maybe slightly faster then for loop, because Vector can utilize System.arraycopy() on its internal array.
This will do it:
double matrix[][] = new double[vector.size()][];
for (int i = 0; i < vector.size(); i++) {
matrix[i] = vector.get(i);
}
Note that this references the same double[] arrays as in your Vector<double[]>. So a change in that will be reflected in the new matrix[][]. If you don't want that then you'll have to create a new double[] for each iteration and copy the values from the old array to the new array.
Muhammed,
WhiteFang is correct... if you're looking for an "out of the box" solution then have a look at Apache's Commons Collections (http://commons.apache.org/collections/)
It's been over a year since I touched Java, but if I recall correctly, "commons" has converters for Vectors... as well as many, many, many other handy bits of kit.
And BTW: If using a Vector is your choice, and you don't have a good reason to NOT use an ArrayList, then use an ArrayList... It's slightly quicker. Except it's NOT threadsafe; whereas all Vectors methods are syncronised. Explanation here: http://skeletoncoder.blogspot.com/2006/09/java-tutorials-arraylist-or-vector.html.
Cheers. Keith.
I need to sort an array based on the positions held in another array.
What I have works, but it is kinda slow, is there a faster/better way to implement this?
2 Parts:
Part1
int i = mArrayName.size();
int temp = 0;
for(int j=0;j<i;j++){
temp = mArrayPosition.get(j);
mArrayName.set(temp, mArrayNameOriginal.get(j));
}
In this part, mArrayPosition is the position I would like the mArrayName to be in.
Ex.
input:
mArrayName= (one, two, three)
mArrayPosition = (2,0,1)
output:
mArrayName= (three, one two)
Part 2
int k=0;
int j=0;
do{
if(mArrayName.get(k)!=mArrayNameOriginal.get(j)){
j++;
}else{
mArrayIdNewOrder.set(k, mArrayId.get(j));
k++;
j=0;
}
}while(k < mArrayName.size());
}
In this part, mArrayName is the reordered name array, mArrayNameOriginal is the original name array.
Ex.
mArrayName = (three, one, two)
mArrayNameOriginal = (one, two, three)
Now I want to compare these two arrays, find which entries are equal and relate that to a new array that has their rowId number in it.
Ex.
input:
mArrayId = (001,002,003)
output:
mArrayIdNewOrder = (003,001,002)
So then I will have mArrayIdNewOrder id's matching up with the correct names in mArrayName.
Like I said these methods work, but is there a faster/better way to do it? I tried looking at Arrays.sort and comparators but they only seem to sort alphabetically or numerically. I saw something like I can create my own rules inside the comparator but it would probably end up being similar to what I already have.
Sorry for the confusing question. I'll try to clear up any ambiguities if needed.
The best performance read I've found is Android's Designing For Performance doc. You are violating a couple of the "Android way" style of doing things that will help you.
You are using multiple internal getters inside each loop for what looks like a simple value. Redo this by accessing the fields directly.
For extra credit, post your performance comparison results! I'd love to see em!
You could use some form of tuple, some class to hold both id and name. You'll just to have a java.util.Comparator that compares it accordingly, both elements will move together and your code will be cleaner.
This data structure might be convenient for the rest of your program... if not, just take things off it again and you're done.
If your order indexes are compact, i.e. from index 0 to size - 1, then just use an array and create the updated list afterwards? About something like
MyArray[] array = new MyArray[size];
for(int j=0;j< size;j++) {
array[ mArrayPosition.get(j) ] = mArrayName.get(j);
}
// create ArrayList from array
Is there any equivalent of String.indexOf() for arrays? If not, is there any faster way to find an array within another other than a linear search?
Regardless of the elements of your arrays, I believe this is not much different than the string search problem.
This article provides a general intro to the various known algorithms.
Rabin-Karp and KMP might be your best options.
You should be able to find Java implementations of these algorithms and adapt them to your problem.
List<Object> list = Arrays.asList(myArray);
Collections.sort(list);
int index = Collections.binarySearch(list, find);
OR
public static int indexOf(Object[][] array, Object[] find){
for (int i = 0; i < array.length(); i ++){
if (Arrays.equals(array[i], find)){
return i;
}
}
return -1;
}
OR
public static int indexOf(Object[] array, Object find){
for (int i = 0; i < array.length(); i ++){
if (array[i].equals(find)){
return i;
}
}
return -1;
}
OR
Object[] array = ...
int index = Arrays.asList(array).indexOf(find);
As far as I know, there is NO way to find an array within another without a linear search. String.indexOf uses a linear search, just inside a library.
You should write a little library called indexOf that takes two arrays, then you will have code that looks just like indexOf.
But no matter how you do it, it's a linear search under the covers.
edit:
After looking at #ahmadabolkader's answer I kind of take this back. Although it's still a linear search, it's not as simple as just "implement it" unless you are restricted to fairly small test sets/results.
The problem comes when you want to see if ...aaaaaaaaaaaaaaaaaab fits into a string of (x1000000)...aaaaaaaaab (in other words, strings that tend to match most places in the search string).
My thought was that as soon as you found a first character match you'd just check all subsequent characters one-on-one, but that performance would degrade terrifyingly when most of the characters matched most of the time. There was a rolling hash method in #a12r's answer that sounded much better if this is a real-world problem and not just an assignment.
I'm just going to vote for #a12r's answer because of those awesome Wikipedia references.
The short answer is no - there is no faster way to find an array within an array by using some existing construct in Java. Based on what you described, consider creating a HashSet of arrays instead of an array of arrays.
Normally the way you find things in collections in java is
put them in a hashmap (dictionary) and look them up by their hash.
loop through each object and test its equality
(1) won't work for you because an array object's hash won't tell you that the contents are the same. You could write some sort of wrapper that would create a hashcode based on the contents (you'd also have to make sure equals returned values consistent with that).
(2) also will require a bit of work because object equality for arrays will only test that the objects are the same. You'd need to wrap the arrays with a test of the contents.
So basically, not unless you write it yourself.
You mean you have an array which elements also are array elements? If that is the case and the elements are sorted you might be able to use binarysearch from java.util.Arrays