I'm working on a programm in which I want my object "this" will be an array of Point but I have this error when I run the programm and I'm not understand why.
Error --> DouglasPeucker.
My programm :
public class DouglasPeucker {
private double epsilon;
protected Point[] coinImage;
public DouglasPeucker(Point [] tab) {
this.coinImage = new Point[tab.length];
for(int i = 0; i < this.coinImage.length; i++) {
double abscisse = tab[i].getX();
double ordonnee = tab[i].getY();
System.out.println(abscisse + " " + ordonnee);
this.coinImage[i].setX(abscisse);
this.coinImage[i].setY(ordonnee);
}
}
You're never assigning a value to coinImage[i], so it will have its default value of null, which you're the dereferencing. You need something like:
for(int i = 0; i < this.coinImage.length; i++) {
double abscisse = tab[i].getX();
double ordonnee = tab[i].getY();
System.out.println(abscisse + " " + ordonnee);
this.coinImage[i] = new Point();
this.coinImage[i].setX(abscisse);
this.coinImage[i].setY(ordonnee);
}
Or preferrably, IMO:
for (int i = 0; i < this.coinImage.length; i++) {
// I'm assuming Point has a sensible constructor here...
coinImage[i] = new Point(tab[i].getX(), tab[i].getY());
// Insert the diagnostics back in if you really need to
}
Related
Basically I'm making a domino game in Java; however I'm pretty new and can't figure out how to shuffle the dominoes up using arrays and buffered Images.
This code here is setting up the arrays for each hand and an array with each domino piece. Keep in mind that I am not using an AI for this domino game;
the program runner will just play as each player.
static String [] hand1 = new String[7];
static String [] hand2 = new String[7];
static String [] hand3 = new String[7];
static String [] hand4 = new String[7];
static String[] allDominoes = {"00","01","02","03","04","05","06","11","12","13","14","15","16","22","23",
"24","25","26","33","34","35","36","44","45","46","55","56","66"};
This is what I tried to use to shuffle the dominoes and put them into each hand array:
public static void newRound() // start a new round; shuffle the dominoes; hand them out
{
Arrays.fill(hand1, null);
Arrays.fill(hand2, null);
Arrays.fill(hand3, null);
Arrays.fill(hand4, null);
String[] shuffledDominos = new String[28];
List<String> shuffled = Arrays.asList(allDominoes);
Collections.shuffle(shuffled);
shuffled.toArray(shuffledDominos);
int pos = 0;
for (int j = 0; j < 7; j++)
{
hand1[pos] = shuffledDominos[j];
pos++;
}
pos = 0;
for (int y = 7; y < 14; y++)
{
hand2[pos] = shuffledDominos[y];
pos++;
}
pos = 0;
for (int x = 14; x < 21; x++)
{
hand3[pos] = shuffledDominos[x];
pos++;
}
pos = 0;
for (int z = 21; z < 28; z++)
{
hand4[pos] = shuffledDominos[z];
pos++;
}
However I think this part is completely wrong and there must be a better way of doing this since I'm not sure how to actually proceed from here on out.
This is assigning each domino Image the domino pngs.
public DominoPanel()
{
try
{
dom00 = ImageIO.read(DominoPanel.class.getResource("/Image/00.png"));
dom01 = ImageIO.read(DominoPanel.class.getResource("/Image/01.png"));
dom02 = ImageIO.read(DominoPanel.class.getResource("/Image/02.png"));
dom03 = ImageIO.read(DominoPanel.class.getResource("/Image/03.png"));
dom04 = ImageIO.read(DominoPanel.class.getResource("/Image/04.png"));
dom05 = ImageIO.read(DominoPanel.class.getResource("/Image/05.png"));
dom06 = ImageIO.read(DominoPanel.class.getResource("/Image/06.png"));
dom11 = ImageIO.read(DominoPanel.class.getResource("/Image/11.png"));
dom12 = ImageIO.read(DominoPanel.class.getResource("/Image/12.png"));
dom13 = ImageIO.read(DominoPanel.class.getResource("/Image/13.png"));
dom14 = ImageIO.read(DominoPanel.class.getResource("/Image/14.png"));
dom15 = ImageIO.read(DominoPanel.class.getResource("/Image/15.png"));
dom16 = ImageIO.read(DominoPanel.class.getResource("/Image/16.png"));
dom22 = ImageIO.read(DominoPanel.class.getResource("/Image/22.png"));
dom23 = ImageIO.read(DominoPanel.class.getResource("/Image/23.png"));
dom24 = ImageIO.read(DominoPanel.class.getResource("/Image/24.png"));
dom25 = ImageIO.read(DominoPanel.class.getResource("/Image/25.png"));
dom26 = ImageIO.read(DominoPanel.class.getResource("/Image/26.png"));
dom33 = ImageIO.read(DominoPanel.class.getResource("/Image/33.png"));
dom34 = ImageIO.read(DominoPanel.class.getResource("/Image/34.png"));
dom35 = ImageIO.read(DominoPanel.class.getResource("/Image/35.png"));
dom36 = ImageIO.read(DominoPanel.class.getResource("/Image/36.png"));
dom44 = ImageIO.read(DominoPanel.class.getResource("/Image/44.png"));
dom45 = ImageIO.read(DominoPanel.class.getResource("/Image/45.png"));
dom46 = ImageIO.read(DominoPanel.class.getResource("/Image/46.png"));
dom55 = ImageIO.read(DominoPanel.class.getResource("/Image/55.png"));
dom56 = ImageIO.read(DominoPanel.class.getResource("/Image/56.png"));
dom66 = ImageIO.read(DominoPanel.class.getResource("/Image/66.png"));
}
catch(Exception E)
{
}
I know I probably didn't explain this well so I will try to summarize it here as best as I can. I need to be able to assign a random domino to each player and then print them out in a JPanel using buffered Images.
I'm attempting to create a programme which tracks the emails of people. I am using a string for the vertex in my graph (The string is their email) and a DefaultWeightedEdge from Jgrapht. If these people send one email between each other then the weight of the edge connecting that node is set to 1. If they send another email after already having sent one I increment the edge weight by 1.
I think I have the main bulk of the code correct, however I am getting this exception.
Exception in thread "main" java.lang.IllegalArgumentException: loops
not allowed at
org.jgrapht.graph.AbstractBaseGraph.addEdge(AbstractBaseGraph.java:203)
at groupProject.Analysis.StoreEmails(Analysis.java:58) at
groupProject.AnalyserRun.main(AnalyserRun.java:7)
Here is my code:
public class Analysis {
SimpleWeightedGraph<String, DefaultWeightedEdge> graph = new SimpleWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class);
jsonParser jP = new jsonParser("/Users/Kieran/test/test2.json");
int numEmails = jP.getNumEmails();
ArrayList<String> senders = new ArrayList<String>();
ArrayList<String> recipients = new ArrayList<String>();
ArrayList<String> all = senders;
ArrayList<DefaultWeightedEdge> edges = new ArrayList<DefaultWeightedEdge>();
public void StoreEmails(){
//Creates vertex's for every sender
for(int i = 0; i < numEmails; i++){
Email email = jP.parseJSON(i);
if(!senders.contains(email.getSender())){
graph.addVertex(email.getSender());
senders.add(email.getSender());
}
}
//creates vertex's for every recipient
for(int i = 0; i < numEmails; i++){
Email email = jP.parseJSON(i);
if(email.getRecipients().length != 0){
for(int j = 0; j < email.getRecipients().length; j++){
if(!recipients.contains(email.getRecipients()[j])){
graph.addVertex(email.getRecipients()[j]);
recipients.add(email.getRecipients()[j]);
}
}
}
}
all.removeAll(recipients);
all.addAll(recipients);
/*
* Adds all of the edges from senders to recipients and if the edge already exists then it will increase the weight by one
* however is is a directed graph so you need to check both pairs.
*/
for(int j = 0; j < numEmails; j++){
Email email = jP.parseJSON(j);
for(int k = 0; k < email.getRecipients().length; k++){
if(graph.containsEdge(email.getSender(), email.getRecipients()[k])){
int current_weight = (int) graph.getEdgeWeight(graph.getEdge(email.getSender(), email.getRecipients()[k]));
graph.setEdgeWeight(graph.getEdge(email.getSender(), email.getRecipients()[k]), current_weight+1);
}else{
DefaultWeightedEdge e = graph.addEdge(email.getSender(), email.getRecipients()[k]);
graph.setEdgeWeight(e, 1);
}
}
}
builder();
}
public int calcConnectedness(String s1,String s2){
int connectedness = 0;
int weightS1S2 = 0;
int weightS2S1 = 0;
if(graph.containsEdge(s1, s2)){
weightS1S2 = (int) graph.getEdgeWeight(graph.getEdge(s1, s2));
connectedness += weightS1S2;
}
/*if(graph.containsEdge(s2, s1)){
weightS2S1 = (int) graph.getEdgeWeight(graph.getEdge(s2, s1));
connectedness += weightS2S1;
}*/
return connectedness;
}
public void builder(){
for(int i = 0; i < all.size(); i++){
for(int j = i+1; j < all.size(); j++){
if(graph.containsEdge(all.get(i), all.get(j)))
make(all.get(i), all.get(j), calcConnectedness(all.get(i), all.get(j)));
}
}
}
public void make(String user1, String user2, int connectedness){
System.out.println(user1 + " " + user2 + " Are connected by a factor of: "+connectedness);
}
}
After some research the only information I was able to find which may be causing the problem is the fact that in Java, strings are immutable. However, I was still not able to resolve my issues.
The answer was in this section of code:
}else{
DefaultWeightedEdge e = graph.addEdge(email.getSender(), email.getRecipients()[k]);
graph.setEdgeWeight(e, 1);
}
It turns out that email.getSender() was in email.getRecipients() so the source and destination of the edge was the same i.e a loop. I solved the issue by doing a simple check beforehand with an if statement to only add an edge if it was not the same as the source.
I have two classes: class Creature which contains ArrayList boids, and class Food.
Boids have a few parameters:
Creature(float posX, float posY, int t, int bth, int ah) {
location = new PVector(posX, posY);
vel = new PVector(random(-5,5), random(-5, 5));
acc = new PVector();
type = t;
if (t == 1) { btype = bth; }
else { health = bth; }
if (t == 1) { age = ah; }
else { hunger = ah; }
wdelta = 0.0;
action = 0;
if (btype == 1) { mass = 5.0; }
else { mass = 7.0; }
}
Food class has this method:
void foodtime(ArrayList boids) {
for (int i = 0; i < boids.size(); i++) {
Creature boid = (Creature) boids.get(i);
float distance = PVector.dist(location, boid.location);
if (distance < 0.5) {
bnumadj = i;
count++;
if (count == quantity) {
planet.food.remove(this);
count = 0;
bnumadj = -1;
}
}
}
}
What I'm trying to achieve is that if a boid "eats" the food, their boid type (btype) changes from 2 to 1.
I'm trying to use bnumadj variable to feed it back to the boid in this method:
void boid(ArrayList boids) {
for (int i = 0; i < boids.size(); i++) {
if (i == bnumadj) {
this.btype = 1;
bnumadj = -1;
}
}
}
Where am I going wrong?
This seems like a very convoluted way to do this, so I'm not surprised you're having issues. You're comparing values to indexes, which doesn't make a ton of sense to me.
Instead, try using a simple nested loop to do what you want. You can use an Iterator to make it easier to remove items while iterating.
ArrayList<Creature> boids = new ArrayList<Creature>();
ArrayList<Food> food = new ArrayList<Food>();
//populate ArrayLists
void draw(){
for(Creature boid : boids){
Iterator<Food> foodIter = food.iterator();
while(foodIter.hasNext()){
Food f = foodIter.next();
float distance = PVector.dist(boid.location, food.location);
if (distance < 0.5) {
boid.btype = 1;
foodIter.remove(); //removes the food
}
}
}
//draw the scene
}
I suppose you could move the second iteration using the Iterator inside the Creature type, but the basic idea is this: keep it simple by using an Iterator to remove the Food instead of trying to match indexes.
I want to implement Levenberg Marquardt fitting in JAVA and found apache commons math suitable. Since I want to fit a function, where I dont have the derivative to calculate the gradient or Jacobian, I need somthing like dfdp.m from GNU octave to calculate numerical derivatives. Has someone done this already?
I did it myself, in case someone else needs it here is the approach
dfdp.m code
m=size(x,1); if (m==1), m=size(x,2); end %# PAK: in case #cols > #rows
n=length(p); %dimensions
ps=p; prt=zeros(m,n);del=zeros(n,1); % initialise Jacobian to Zero
for j=1:n
del(j)=dp(j) .*p(j); %cal delx=fract(dp)*param value(p)
if p(j)==0
del(j)=dp(j); %if param=0 delx=fraction
end
p(j)=ps(j) + del(j);
if del(j)~=0, f1=feval(func,x,p); %FJ ~= not equal (!=) ...> p is now (p + dp*p)
if dp(j) < 0, prt(:,j)=(f1-f)./del(j);
else
p(j)=ps(j) - del(j); %FJ ...> p is now (p - dp*p)
prt(:,j)=(f1-feval(func,x,p))./(2 .*del(j)); %FJ 2 steps from (ps + del) to (ps - del)
end
end
p(j)=ps(j); %restore p(j)
end
JAVA code
private static class GhoosProblem {
private double[][] data;
private double[] dp;
public GhoosProblem(double[][] datapoints, double[] delta_p) {
data = datapoints;
//dp= fractional increment of p for numerical derivatives
//dp(j)>0 central differences calculated
//dp(j)<0 one sided differences calculated
//dp(j)=0 sets corresponding partials to zero; i.e. holds p(j) fixed
dp = delta_p;
}
public MultivariateVectorFunction getModelFunction() {
return new MultivariateVectorFunction() {
public double[] value(double[] params) {
double[] values = new double[data.length];
for (int i = 0; i < values.length; ++i) {
final double t = data[i][0]; // get the double value
values[i] = params[0] *
Math.pow(t, params[2]) *
Math.exp(-params[1] * t); // Ghoos function
}
return values; // function values
}
};
}
public MultivariateMatrixFunction getModelFunctionJacobian2() {
return new MultivariateMatrixFunction() {
public double[][] value(double[] params) {
double[][] jacobian = new double[data.length][params.length];
final double a = params[0];
final double b = params[2];
final double c = params[1];
for (int i = 0; i < jacobian.length; ++i) {
final double t = data[i][0]; // get the double value
jacobian[i][0] = Math.pow(t, b) * Math.exp(-c*t);
jacobian[i][2] = a * Math.exp(-c*t) * Math.pow(t, b) * Math.log(t);
jacobian[i][1] = a * Math.pow(t, b) * (-t*Math.exp(-c*t));
}
//System.out.println("Jacobian= "+ Arrays.deepToString(jacobian));
return jacobian;
}
};
}
// compared to Ge2.m octave
public MultivariateMatrixFunction getModelFunctionJacobian() {
return new MultivariateMatrixFunction() {
public double[][] value(double[] params) {
int m = data.length; // cols
int n = params.length; // rows
double[] p = params;
double[] ps = params;
double[] del = new double[n];
double[] f = new double[n];
double[] f1 = new double[n];
BlockRealMatrix prt = new BlockRealMatrix(m, n); // initializes to zeros
f=feval(p);
for (int j=0; j<n; ++j) {
del[j]=dp[j] * p[j]; //delta_x=fractional(dp) * param value(p)
if (p[j]==0)
del[j]=dp[j]; //if param=0 delta_x=fractional(dp)
p[j]=ps[j] + del[j];
if (del[j]!=0) {
f1=feval(p); //p is now (p + dp*p)
if (dp[j]<0)
prt.setColumn(j,(new ArrayRealVector(f1)).subtract(new ArrayRealVector(f)).mapDivideToSelf(del[j]).toArray()); // one sided diff
else {
p[j]=ps[j] - del[j]; // p is now (p - dp*p)
prt.setColumn(j,(new ArrayRealVector(f1)).subtract(new ArrayRealVector(feval(p))).mapDivideToSelf(2*del[j]).toArray()); // central diff
}
}
p[j]=ps[j]; //restore p(j)
}//for
//System.out.println("Jacobian= "+ Arrays.deepToString(prt.getData()));
return prt.getData(); //jacobian, dimension is (m x n)
}
};
}
public double[] feval(double[] params) {
double[] values = new double[data.length];
for (int i = 0; i < values.length; ++i) {
final double t = data[i][0]; // get the double value
values[i] = params[0] *
Math.pow(t, params[2]) *
Math.exp(-params[1] * t); // Ghoos function
}
return values;
}
}//GhoosProblem
sorry if idention of code did not come out nice!
the relevant part is the getModelFunctionJacobian() -Function
I have renamed the analytical derivatives part as getModelFunctionJacobian2(), and posted here for comparison
to complete with here is the levenberg marquardt setup to use the GhoosFunction
public void fit() {
final double[][] dataPoints = { // x, y
//{0.0/60, 0.0}, // never use {0, 0} => org.apache.commons.math3.exception.ConvergenceException: illegal state: unable to perform Q.R decomposition on the 17x3 jacobian matrix
{15.0/60, 8.891104},
{30.0/60, 13.21852},
{45.0/60, 28.09051},
{60.0/60, 43.0011},
{75.0/60, 57.43561},
{90.0/60, 67.06862},
{105.0/60, 82.60239},
{120.0/60, 72.4649},
{135.0/60, 61.4},
{150.0/60, 43.97924},
{165.0/60, 30.6},
{180.0/60, 20.77112},
{195.0/60, 15.5},
{210.0/60, 10.85442},
{225.0/60, 9.33},
{240.0/60, 7.260234},
};
final double[] initialGuess = { 1.0, 1.0, 1.0 }; // p
final double[] fract_change = { 1E-4, 1E-4, 1E-4 }; // dp should be below 0.0001
final GhoosProblem problem = new GhoosProblem(dataPoints, fract_change);
final int len = dataPoints.length;
final double[] weights = new double[len];
final double[] target = new double[len];
for (int i = 0; i < len; i++){
weights[i] = 1.0;// / dataPoints[i][1];
target[i] = dataPoints[i][1];
}
final LevenbergMarquardtOptimizer optimizer = new LevenbergMarquardtOptimizer()
.withCostRelativeTolerance(1E-4) // stol in octave
.withParameterRelativeTolerance(1E-4); // dp should be below 0.0001
final Optimum optimum = optimizer.optimize(
builder(problem)
.weight(new DiagonalMatrix(weights))
.target(target)
.start(initialGuess)
.maxIterations(100)
.build()
);
final RealVector solution = optimum.getPoint();
solution.setEntry(0, solution.getEntry(0) / 60.0); // go back to minutes
System.out.println("solution= " + solution);
System.out.println("CostRelativeTolerance= " + optimizer.getCostRelativeTolerance());
System.out.println("ParameterRelativeTolerance= " + optimizer.getParameterRelativeTolerance());
System.out.println("evaluations= " + optimum.getEvaluations());
System.out.println("iterations= " + optimum.getIterations());
//System.out.println("residuals= " + optimum.getResiduals());
System.out.println("RMS= " + optimum.getRMS());
System.out.println("sigma= " + optimum.getSigma(1E-10));
}//fit
public LeastSquaresBuilder builder(GhoosProblem problem){
return new LeastSquaresBuilder()
.checkerPair(new SimpleVectorValueChecker(1e-6, 1e-6)) // The SimpleVectorValueChecker Class (Simple implementation of the ConvergenceChecker) contains a method that uses the value of the function between two successive iterations of the optimisation algorithm to check if convergence has occured
.maxEvaluations(Integer.MAX_VALUE)
.maxIterations(Integer.MAX_VALUE)
//.lazyEvaluation(true)
.model(problem.getModelFunction(), problem.getModelFunctionJacobian());
}
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.