I've been issued the task of using MATLAB Builder to convert a MATLAB function into a Java class, now I have gotten to a point where I have the results from one class being fed into another and since the MATLAB builder will only output an object, I'm having issues.
import java.util.*;
import com.mathworks.toolbox.javabuilder.*;
public class mainKrigTau {
public static void main(String[] args) {
Object[] resultT = null;
Object[] resultK = null;
Object[] resultB = null;
krigingTau Tau = null;
krigingTau Krig = null;
Branin branin = null;
try {
Tau = new krigingTau();
Krig = new krigingTau();
branin = new Branin();
resultT = Tau.LPtau(1, 100, 2, 1234);
List<Object> X = Arrays.asList(resultT[0]);
System.out.println(X);
System.out.println((X.size()));
} catch (MWException e)
{
e.printStackTrace();
} finally
{
}
So basically the output of the Tau class is a 2D array, so the array is embedded into the resultT[] object, how to I get access to this array? One method I have tried is as above, changing it into an array list, X outputs the array, but I can't access the components of the array. X.size = 1, not 100 which is the actual size of the array. edit - just to add, all the examples I can find just output the result object and display it, rather than do anything with it.
Okay a software engineer nearby came to the rescue. It's a bit of a roundabout way but it works.
try {
Tau = new krigingTau();
Krig = new krigingTau();
branin = new Branin();
resultT = Tau.LPtau(1, 100, 2, 1234);
List<Object> X = Arrays.asList(resultT[0]);
if (X.get(0) instanceof MWNumericArray) {
MWNumericArray mw= (MWNumericArray) X.get(0);
ArrayList<Point> lists = new ArrayList<Point>();
for(int i = 1; i <= mw.numberOfElements()/2; i++){
Object o = mw.get(i);
System.out.println(o);
Double x = (Double) mw.get(i);
Double y = (Double) mw.get((mw.numberOfElements()/2)+i);
Point p = new Point(x.doubleValue(),y.doubleValue());
lists.add(p);
}
for(int i = 1; i < mw.numberOfElements()/2; i++)
{
resultB = branin.branin(1, lists.get(i).array);
System.out.println(resultB[0]);
}
where point sets the values of x and y into an array, so set it to an new MWNumericArray and do Object.get(i) but this flattens the array which is not ideal.
Related
Lets say I have a public class called GameBoard that will be a two dimensional array with 4 rows and 5 columns. The spaces in the array are filed with String values from 1 to 20. A card will be drawn that has a name (King of Spades for example) . If the user inputs 15 I will store it in a String variable called userLocation. What would be the most efficient way to create a method that takes the input location and updates the array with the name of the Card? Would a for loop be most efficient?
public GameBoard() {
square = new String[4][5];
square[0][0] = new String("1");
square[0][1] = new String("2");
square[0][2] = new String("3");
square[0][3] = new String("4");
square[0][4] = new String("5");
square[1][0] = new String("6");
square[1][1] = new String("7");
square[1][2] = new String("8");
square[1][3] = new String("9");
square[1][4] = new String("10");
square[2][1] = new String("11");
square[2][2] = new String("12");
square[2][3] = new String("13");
square[3][1] = new String("14");
square[3][2] = new String("15");
square[3][3] = new String("16");
square[2][0] = new String(17);
square[3][0] = new String(18);
square[2][4] = new String(19);
square[3][4] = new String(20);
}
My preferred method as of now would look something like this but it gives me the error code "type mismatch:cannot convert string to boolean" under userLocation = board[i][j]
public String[][] updateBoard(String userLocation, Card card, String[][] board) {
for (int i = 0; i <4; i++)
{
for (int j = 0; j < 5; j++)
{
if(userLocation = board[i][j]) {
board[i][j] = card.name;
}
}
}
return board;
}
So the reason it will not compile is your = does not return a boolean expression. == would, but it's still not what you want, since you want to check if the String contents are the same, not if they're the same object, so use .equals.
But, no, I think you don't want to depend on strings to identify locations. What if you want to replace a card? And why look through everything when you need not?
Rather if i is some number between 1 and 20, identify the corresponding spot in the array by square[(i-1)/5][(i-1)%5]
That should bypass the issue you are having with matching strings.
So for example, your constructor becomes:
public GameBoard() {
square = new String[4][5];
for (int i=1; i<=20;i++){
square[(i-1)/5][(i-1)%5]=""+i;//initialize with 1 to 20 if you like
}
and userLocation is an int.
I am relative new to java and i need help to use matrix with async Task.
I am using input frame from onCameraFrame to analysis in background.
I will provide the method and async Task.
public int recognize(Mat inputFrame) {
int detector=0;
Mat gray= inputFrame;
if (startedFrame){
BRISK.detect(inputFrame,keypoints1);
BRISK.compute(inputFrame,keypoints1,deskriptor1);
startedFrame=false;
return 0;
}
BRISK.detect(inputFrame,keypoints2);
BRISK.compute(inputFrame,keypoints2,deskriptor2);
List<MatOfDMatch> matches = new LinkedList<MatOfDMatch>();
matcher.knnMatch(deskriptor1, deskriptor2, matches,2);
//Calculating good match list...
LinkedList<DMatch> goodMatchesList = new LinkedList<DMatch>();
for (int i = 0; i < matches.size(); i++) {
MatOfDMatch matofDMatch = matches.get(i);
DMatch[] dmatcharray = matofDMatch.toArray();
DMatch m1 = dmatcharray[0];
DMatch m2 = dmatcharray[1];
if (m1.distance <= m2.distance * nndrRatio) {
goodMatchesList.addLast(m1);
}
}
if (goodMatchesList.size() >= 7) {
List<KeyPoint> controlKeypointlist = keypoints1.toList();
List<KeyPoint> liveKeypointlist = keypoints2.toList();
LinkedList<Point> objectPoints = new LinkedList<>();
LinkedList<Point> scenePoints = new LinkedList<>();
for (int i = 0; i < goodMatchesList.size(); i++) {
objectPoints.addLast(controlKeypointlist.get(goodMatchesList.get(i).queryIdx).pt);
scenePoints.addLast(liveKeypointlist.get(goodMatchesList.get(i).trainIdx).pt);
}
MatOfPoint2f objMatOfPoint2f = new MatOfPoint2f();
objMatOfPoint2f.fromList(objectPoints);
MatOfPoint2f scnMatOfPoint2f = new MatOfPoint2f();
scnMatOfPoint2f.fromList(scenePoints);
detector=1;
keypoints2.release();
deskriptor2.release();
return 2;
}
return 1;
}
class MyTask extends AsyncTask<Mat, Void, Integer> {
#Override
protected Integer doInBackground(Mat... mats) {
return recognize(mats);
}
}
And problem is in return recognize(mats);,in parametar matswhere it say:recognize (org.opencv.core.Mat) in MainActivity cannot be applied
to (org.opencv.core.Mat[]) and i do not know how to solve it?Thanks in advance.
The parameter Mat... is a varargs parameter and acts like an array. (i.e. Mat[]).
To get the first Mat of the arguments use mats[0]:
#Override
protected Integer doInBackground(Mat... mats) {
return recognize(mats[0]);
}
In Java Mat... represents an array of Mat class type. If you look at the error
recognize (org.opencv.core.Mat) in MainActivity cannot be applied to (org.opencv.core.Mat[])
You'll notice that it says exactly the same thing i.e. you are passing an Array to a method which takes a single instance. So all you need to do is:
return recognize(mats[0]);
get the Mat at the first index of this array.
I wrote a physical simulation about gravitational force between two planets.It worked perfectly fine so I decided to take it to a new level and rewrote it using arrays and five planets(circles).But my code gives strange and never the same error. I get either NullPointerException error or the VM error when intializing the sketch(No description just the "Vm error couldn't initialize skecth" and the "see help and troubleshoot" bullsh*t) The program uses a txt file to read in data(double-checked and it works fine).
My Array names and descriptions are
PVector - Pos stands for Position
PVector - Vel stands for Velocity
PVector - Acc stands for Acceleration
PVector - Dist stands for Distance
PVector - Dir stands for Direction
float - Mass stands for Mass
My code:
public PVector[] Pos = new PVector[5];
public PVector[] Acc = new PVector[5];
public PVector[] Vel = new PVector[5];
public PVector[] Dist = new PVector[5];
public PVector[] Dir = new PVector[5];
public float[] Mass = new float[5];
void setup(){
String Data[] = loadStrings("Data.txt");
size(800,800);
for(int g = 0;g < 5;g++){
Pos[g] = new PVector(float(Data[g+1]),float(Data[g+6]));
Vel[g] = new PVector(float(Data[g+12]),float(Data[g+17]));
Mass[g] = float(Data[g+23]);
}
}
void draw(){
for (int i = 0;i < 5;i++){
for (int f = 0;f < 5;f++){
if(i !=f){
if(Pos[i].x < Pos[f].x){Dir[f].x = 1;Dist[f].x = (Pos[f].x - Pos[i].x);}else{ // I get the error here
if(Pos[i].x > Pos[f].x){Dir[f].x = -1;Dist[f].x = (Pos[i].x - Pos[f].x);}else{
if(Pos[i].x == Pos[f].x){Dir[f].x = 0;Dist[f].x = 0;}}}
if(Pos[i].y < Pos[f].y){Dir[f].y = 1;Dist[f].y = (Pos[f].y - Pos[i].y);}else{
if(Pos[i].y > Pos[f].y){Dir[f].y = -1;Dist[f].y = (Pos[i].y - Pos[f].y);}else{
if(Pos[i].y == Pos[f].y){Dir[f].y = 0;Dist[f].y = 0;}}}
if ((Dist[f].x != 0)){
Acc[i].x+=((6*((Mass[i]*Mass[f])/Dist[f].magSq())/10000000)/Mass[i])*Dir[f].x;// *6/1000000 is MY G constant
}
if ((Dist[f].y != 0)){
Acc[i].y+=((6*((Mass[i]*Mass[f])/Dist[f].magSq())/10000000)/Mass[i])*Dir[f].y;
}
}
}
Vel[i].x = Vel[i].x + Acc[i].x;
Vel[i].y = Vel[i].y + Acc[i].y;
Pos[i].x = Pos[i].x + Vel[i].x;
Pos[i].y = Pos[i].y + Vel[i].y;
ellipse(Pos[i].x,Pos[i].y,10,10);
}
}
You create array of PVectors of size 5 here : public PVector[] Dir = new PVector[5]; . In this moment, it has null five times for indexes 0-4 in it.
Because you do not create new PVectors in this array, when you try to access variable x in here Dir[f].x, you got error, because Dir[f] is null and you cant access variable x of null -> NullPointerException.
In this part you are instantizing some arrays
for(int g = 0;g < 5;g++){
Pos[g] = new PVector(float(Data[g+1]),float(Data[g+6]));
Vel[g] = new PVector(float(Data[g+12]),float(Data[g+17]));
Mass[g] = float(Data[g+23]);
}
You should add instantizing also for Dir, Acc and Dist
Note also, that you are working with objects, not with primitive data types. null is not same as new PVector(0,0)
Also from "design" point of view, using arrays this way is NOT good approach. You should create your own class Planet, where each planet holds information about its properties and in your main class you handle interaction between them.
How to create "empty" or "zero" variables instead of nulls? Just create them :)
for(int g = 0;g < 5;g++){
Pos[g] = new PVector(float(Data[g+1]),float(Data[g+6]));
Vel[g] = new PVector(float(Data[g+12]),float(Data[g+17]));
Mass[g] = float(Data[g+23]);
Dir[g] = new PVector(0,0);
Acc[g] = new PVector(0,0);
Dist[g] = new PVector(0,0);
}
PS : I do not how exactly is this class implemented, using new PVector() or new PVector(0) instead of new PVector(0,0) may also work.
I try to retreive information from catia usig com4j. Some methods require to pass an array in argument to retreive information but the array is never populated. In this example is to get coordinate from a point in catia.
The declaration of the method generated by com4j
public interface Point extends com4j.catia.HybridShape {
...
void getCoordinates(java.lang.Object[] oCoordinates);
...
}
my code to get the coordinate
public static void testGetPointCoordinates() {
String catiafile="E:\\test.CATPart";
Application app =null;
app = COM4J.createInstance(Application.class, "CATIA.Application");
Documents documents = app.documents();
Document oDocument = (Document) documents.open(new Holder<>(catiaFile.getAbsolutePath()));
PartDocument partDocument = oDocument.queryInterface(PartDocument.class);
Part part = partDocument.part();
Factory HSFactory = part.hybridShapeFactory();
HybridShapeFactory HSF = HSFactory.queryInterface(HybridShapeFactory.class);
HybridBodies hbodies = part.hybridBodies();
int n = hbodies.count();
for (int i = 1; i <= n; i++) {
HybridBody hbody = null;
hbody = hbodies.item(i);
int nbitems = hbody.hybridShapes().count();
for (int j = 1; j <= nbitems; j++) {
String name = hbody.hybridShapes().item(j).name();
System.out.println("name=" + name);
//Object tab[]=new Object[3];
if (name.startsWith("Point.12")) {//true point
HybridShape hs = hbody.hybridShapes().item(j);
Reference reference = part.createReferenceFromObject(hs);
HybridShapePointCoord p3 = hs.queryInterface(HybridShapePointCoord.class);
//works
System.out.println("point name = " + p3.name());
System.out.println(p3.y().value());//display 50.0
//doesn't work
Variant tab[] = new Variant[3];
for (int k = 0; k < 3; k++) {
Variant variant = new Variant();
variant.set(k);
tab[k] = variant;
}
p3.getCoordinates(tab);
System.out.println(tab[1].getParseableString()); //display 1 (value not modified)
//doesn't work
tab = new Variant[3];
for (int k = 0; k < 3; k++) {
Variant variant = new Variant(Variant.Type.VT_EMPTY);//tested with VT_R4 VT_R8,...
tab[k] = variant;
}
System.out.println(tab[1].getJavaCode()); //display null (Don't know how to print VT_EMPTY as an Java literal)
//doesn't work with this other solution but ok in VBA
tab = new Variant[3];
//Variant v = new Variant(Type.VT_EMPTY);
tab[0] = new Variant(Variant.Type.VT_EMPTY);
tab[1] = new Variant(Variant.Type.VT_EMPTY);
tab[2] = new Variant(Variant.Type.VT_EMPTY);
HybridShapePointExplicit point = HSF.addNewPointDatum(reference);
point.getCoordinates(tab);
System.out.println(tab[1].doubleValue() + " " + tab[2].toString()); //display 0
//doesn't work
//crash JVM
// tab = new Variant[3];
// p3.getCoordinates(tab);
break;
}
}
}
}
the code below works in VBA with CATIA
Dim P1
Dim coordonnees(2)
Dim coordonnees2(100, 3)
coordonnees(0) = 0
coordonnees(1) = 0
coordonnees(2) = 0
Set P1 = HSF.AddNewPointDatum(hbody.HybridShapes.Item(i))
'fonction to get coordinates
P1.GetCoordinates coordonnees
'set name and coordinates
coordonnees2(Y, 0) = hbody.HybridShapes.Item(i).name
coordonnees2(Y, 1) = Round(coordonnees(0), 3)
coordonnees2(Y, 2) = Round(coordonnees(1), 3)
coordonnees2(Y, 3) = Round(coordonnees(2), 3)
I'm not familiar with com4j, but Point.GetCoordinates is a restricted method:
.
The solution to this problem in VB is you need to create a new variant and set it equal to p3. Then, call GetCoordinates from the variant's context. Intellisense will not work well on the variant, but the call to GetCoordinates will work.
In VB the code would look something like this:
...
Dim p3 As Variant
Dim arrayOfCoord(2) As Variant
Set p3 = hybridShapePointCoord1 'set variant = strongly typed point object
p3.GetCoordinates arrayOfCoord
...
In your case, non-VB, your code might look like this
...
Object p3Obj; //used in vb:Variant p3Var;
p3Obj = p3;
p3Obj.GetCoordinates(tab);//Intellisense will not work, but the call to this method should
...
Let me know if this works.
I'm trying to do a method that automatically creates a new hashTable with 1.25 more capacity, but I have a overflow error. The code is:
public void reHash (){
Config.MAX_ESTACIONS = (int) (Config.MAX_ESTACIONS * 1.25);
Vector<EstacioHash>[] newHashTable = new Vector[Config.MAX_ESTACIONS];
EstacioHash nouElement = new EstacioHash();
for (int i=0; i<hashTable.length;i++){
for (int k=0; k<hashTable[i].size();k++){
nouElement.key = hashTable[i].get(k).key;
nouElement.value = hashTable[i].get(k).value;
int position = hashFunction(nouElement.key);
newHashTable[position].add(nouElement); <---- OverFlow here
}
}
hashTable = newHashTable;
}
Why I have an overFlow? The programs run correctly without the rehash function. The hash function is:
public int hashFunction (Object clau){
String clauMinuscules = ((String) clau).toLowerCase();
char[] key = clauMinuscules.toCharArray();
int result=0;
for (int i=0;i<key.length;i++){
result = (result + key[i]^i)%Config.MAX_ESTACIONS;
}
return result;
}
I don't think you have an overflow but more a NullPointerException.
The default value for an Object is null. When creating the new table, you have an array full of null values.
You need to initialize each entry of the newHashTable before trying to get the Vector at some position and add something into it.
Vector<EstacioHash>[] newHashTable = new Vector[Config.MAX_ESTACIONS];
for (int i=0; i<newHashTable.length;i++){
newHashTable[i] = new Vector<EstacioHash>();
}