Can't find certain function when calling R within java - java

I'm trying to use R within Java, specifically within Processing.
I want to use the readPNG function, but when I try to, R displays an error readPNG function can't be found. This is extremely weird because I have the png library active and if I try to use it directly from R this workouts just fine. I'm using the Rservepackage to connect java and R. Any advise would be very much appriciated.
Here's part of the code I'm using if it helps.
import org.rosuda.REngine.Rserve.*;
import org.rosuda.REngine.*;
double[] data;
void setup() {
size(300,300);
try {
RConnection c = new RConnection();
// generate 100 normal distributed random numbers and then sort them
data= c.eval("readPNG('juego-11932.png')").asDoubles();
} catch ( REXPMismatchException rme ) {
rme.printStackTrace();
} catch ( REngineException ree ) {
ree.printStackTrace();
}
}
void draw() {
background(255);
for( int i = 0; i < data.length; i++) {
line( i * 3.0, height/2, i* 3.0, height/2 - (float)data[i] * 50 );
}
}

Your Java code connects to a fresh R session so no packages are loaded. Hence you have to either use png::readPNG() or load the png package explicitly.

Related

Wolfram Elementary Cellular Automata Using Processing

I'm using a piece of code taken from the website The Nature of Code - https://natureofcode.com/book/chapter-7-cellular-automata/ - the portion I used was from example 7.1. I'm trying to create a one-dimensional cellular automaton using the Processing IDE, but I keep getting an error saying that brackets are missing from particular locations.
Errors:
-Missing curlry bracket "}", line 32
-Syntax error on "}", delete this, line 40
I've gone over it multiple times, but I can't see how this is wrong. Though I did try changing them as it says, only to get more errors. I thought maybe they were just in the wrong place, but I also can't see how that's the case. They seem to be correct as far as I can tell, but maybe I'm missing something. This is my first time using Processing, and it's been a long time since I last used Java. So maybe I'm mistaken.
class CA {
int[] cells;
int[] ruleset;
int w = 10;
// The CA should keep track of how
// many generations.
int generation = 0;
CA() {
cells = new int[width/w];
ruleset = new int[]{0,1,0,1,1,0,1,0};
cells[cells.length/2] = 1;
}
// Function to compute the next generation
void generate() {
int[] nextgen = new int[cells.length];
for (int i = 1; i < cells.length-1; i++) {
int left = cells[i-1];
int me = cells[i];
int right = cells[i+1];
nextgen[i] = rules(left, me, right);
}
cells = nextgen;
// Increment the generation counter.
generation++;
}
int rules(int a, int b, int c) {
String s = "" + a + b + c;
int index = Integer.parseInt(s,2);
return ruleset[index];
}
for (int i = 0; i < cells.length; i++) {
if (cells[i] == 1) fill(0);
else fill(255);
// Set the y-location according to the generation.
rect(i*w, generation*w, w, w);
}
}
The program is supposed to print each generation of the one-dimensional CA on top of the next.
The for-loop in the end of the CA class is not supposed to be there. That is why you get the error: the parser expects either a method declaration or the end of the class, hence a curly bracket.
It looks like this loop is actually drawing the CA state, so you can try to wrap it in a void draw(){} method. Then it should be syntactically correct, not sure though whether it works as expected. Alternatively move the for-loop outside of the class and call fill based on the the cells state of an instance of the CA class.
In any case, will need some additional code that creates the CA instance and invokes the generate function.

JAVA - Out Of Memory - Voxel World Generation

Currently I have this for code and my game either uses way to much memory when generating (over a GB) or if I set it low, it will give a
WORLD_SIZE_X & WORLD_SIZE_Z = 256;
WORLD_SIZE_Y = 128;
Does anyone know how I could improve this so it doesn't use so much RAM?
Thanks! :)
public void generate() {
for(int xP = 0; xP < WORLD_SIZE_X; xP++) {
for(int zP = 0; zP < WORLD_SIZE_Z; zP++) {
for(int yP = 0; yP < WORLD_SIZE_Y; yP++) {
try {
blocks[xP][yP][zP] = new BlockAir();
if(yP == 4) {
blocks[xP][yP][zP] = new BlockGrass();
}
if(yP < 4) {
blocks[xP][yP][zP] = new BlockDirt();
}
if(yP == 0) {
blocks[xP][yP][zP] = new BlockUnbreakable();
}
} catch(Exception e) {}
}
//Tree Generation :D
Random rX = new Random();
Random rZ = new Random();
if(rX.nextInt(WORLD_SIZE_X) < WORLD_SIZE_X / 6 && rZ.nextInt(WORLD_SIZE_Z) < WORLD_SIZE_Z / 6) {
for(int j = 0; j < 5; j++) {
blocks[xP][5 + j][zP] = new BlockLog();
}
}
}
}
generated = true;
}
Delay object creation until you really need to access one of these voxels. You can write a method (I'm assuming Block as the common subclass of all the Block classes):
Block getBlockAt( int x, int y, int z )
using code similar what you have in your threefold loop, plus using a hash map Map<Integer,Block> for storing the random stuff, e.g. trees: from x, y and z compute an integer (x*128 + y)*256 + z and use this as the key.
Also, consider that for all "air", "log", "dirt" blocks you may not need a separate object unless something must be changed at a certain block. Until then, share a single object of a kind.
Cause you just give small piece of code, I can give you two suggestions:
compact the object size. Seems very stupid but very easy to do. Just imagine you have thousands of objects in your memory. If everyone can be compacted half size, you can save half memory :).
Just assign the value to array when you need it. Sometime it is not work if you need really need a assigned array. So just assign values to elements in array as LESS as you can. If you can show me more code, I can help you more.
Are you sure the problem is in this method? Unless Block objects are really big, 256*256*128 ~= 8M objects should not require 1 GB ...
That said, if the blocks do not hold state, it would be more memory efficient to use an enum (or even a byte instead), as we would not need a separate object for each block:
enum Block {
air, grass, dirt, log, unbreakable;
}
Block[][][] map = ...

Java NullPointerException in agent based model

I am using the MASON library to run a simple agent-based model.
As per specifications, I meant to access an agent's inspector by double-clicking on such agent in the Portrayal.
However, when I do so I get the following console error:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at sim.display.Display2D.createInspectors(Display2D.java:1737)
at sim.display.Display2D$8.mouseClicked(Display2D.java:1392)
I went to Display2D.java:1737 to find:
public void createInspectors( final Rectangle2D.Double rect, final GUIState simulation )
{
Bag inspectors = new Bag();
Bag names = new Bag();
Bag[] hitObjects = objectsHitBy(rect);
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
simulation.controller.setInspectors(inspectors,names); //1737
}
However, this is a library file so I'm not familiar with it.
Any advice?
Library: cs.gmu.edu/~eclab/projects/mason/
Update:
Ok, it gets interesting...
I did an echo on the toString method of inspectors and names, returning:
insepectors sim.util.Bag#1b2202a names sim.util.Bag#16b334d
Ok so they're bags, a type of collection. Time to get their sizes...
insepectors 1 names 1
Good, they're not empty.
Let's follow the error stack
Next bit:
at sim.display.Display2D$8.mouseClicked(Display2D.java:1392)
// add mouse listener for the inspectors
insideDisplay.addMouseListener(new MouseAdapter()
{
public void mouseClicked(MouseEvent e)
{
if (handleMouseEvent(e)) { repaint(); return; }
else
{
// we only care about mouse button 1. Perhaps in the future we may eliminate some key modifiers as well
int modifiers = e.getModifiers();
if ((modifiers & e.BUTTON1_MASK) == e.BUTTON1_MASK)
{
final Point point = e.getPoint();
if( e.getClickCount() == 2 )
1392-> createInspectors( new Rectangle2D.Double( point.x, point.y, 1, 1 ),
Display2D.this.simulation );
if (e.getClickCount() == 1 || e.getClickCount() == 2) // in both situations
performSelection( new Rectangle2D.Double( point.x, point.y, 1, 1 ));
repaint();
}
}
}
Ok, the error is clearly in the CreateInspectors method:
public void createInspectors( final Rectangle2D.Double rect, final GUIState simulation )
{
Bag inspectors = new Bag();
Bag names = new Bag();
Bag[] hitObjects = objectsHitBy(rect);
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
System.out.println("insepectors " + inspectors.size() + " names " + names.size());
simulation.controller.setInspectors(inspectors,names);
}
First thing I do:
System.out.println(rect.getCenterX() + " " + rect.getCenterY());
Which gives me 646.5 659.5. Seem to make sense as coordinates.
So next thing I want to look at hitObjects:
System.out.println(hitObjects.length);
Returns 2. So I had two agents at that coordinates.
I assume the NPE is somewhere here:
for(int x=0;x<hitObjects.length;x++)
{
FieldPortrayal2DHolder p = (FieldPortrayal2DHolder)(portrayals.get(x));
for( int i = 0 ; i < hitObjects[x].numObjs ; i++ )
{
LocationWrapper wrapper = (LocationWrapper) (hitObjects[x].objs[i]);
inspectors.add(p.portrayal.getInspector(wrapper,simulation));
names.add(p.portrayal.getName(wrapper));
}
}
The outer loop looks fine, but I'm having issues with the inner one. Advice?
I'm actually going to write how to reason through the library code given as far as you've come since you sound capable.
You found the code. That's a good start. You've also found the line that it's on:
simulation.controller.setInspectors(inspectors,names); //1737
And given what you know about NPEs you can reason that simulation or controller is null.
Do you know which? Can you reason about your code which you may have failed to set, or passed incorrectly? Can you put a debugger breakpoint or simple println statements in your code to determine which?
If not and you're using an IDE (you probably are), then from the source you just opened up, put a breakpoint before line 1737. When that line is reached, use the debugger to inspect the variable simulation then simulation.controller to see which is null. Exactly how to do this will depend on your IDE but it shouldn't be hard to find using XKCD's tech support cheat sheet.
Then you will probably know the cause. If not, continue reading source code, e.g. look a level up to line 1737.

Does libsvm work for multi output regression?

I have been trying to use jlibSVM
I want to use it for multi output regression.
for example my :
feature set / inputs will be x1,x2,x3
and outputs/target values will be y1,y2
Is this possible using the libSVM library ?
The API docs are not clear and there is not example app showing the use of jlibsvm so I tried to modify the code inside lexecyexec/svm_train.java
The author has originally just created the app to use one output/target value only .
this is seen in this part where the author tries to read the training file :
private void read_problem() throws IOException
{
BufferedReader fp = new BufferedReader(new FileReader(input_file_name));
Vector<Float> vy = new Vector<Float>();
Vector<SparseVector> vx = new Vector<SparseVector>();
int max_index = 0;
while (true)
{
String line = fp.readLine();
if (line == null)
{
break;
}
StringTokenizer st = new StringTokenizer(line, " \t\n\r\f:");
vy.addElement(Float.parseFloat(st.nextToken()));
int m = st.countTokens() / 2;
SparseVector x = new SparseVector(m);
for (int j = 0; j < m; j++)
{
//x[j] = new svm_node();
x.indexes[j] = Integer.parseInt(st.nextToken());
x.values[j] = Float.parseFloat(st.nextToken());
}
if (m > 0)
{
max_index = Math.max(max_index, x.indexes[m - 1]);
}
vx.addElement(x);
}
I tried to modify it so that the vector vy accepts a sparse vector with 2 values.
The program gets executed but the model file seems to be wrong.
Can anyone please verify if they have used jlibsvm for multiple output svm regression???
If yes can someone please explain how they achieved this ??
If no then does someone know of a similar svm implementation in Java ??
The classic SVM algorithm does not support multi dimensional outputs. One way to work around this would be to have a SVM model for each output dimension.

Difference between R.loess and org.apache.commons.math LoessInterpolator

I'm trying to compute the convert a R script to java using the apache.commons.math library. Can I use org.apache.commons.math.analysis.interpolation.LoessInterpolator in place of R loess ? I cannot get the same result.
EDIT.
here is a java program that creates a random array(x,y) and compute the loess with LoessInterpolator or by calling R. At the end, the results are printed.
import java.io.*;
import java.util.Random;
import org.apache.commons.math.analysis.interpolation.LoessInterpolator;
public class TestLoess
{
private String RScript="/usr/local/bin/Rscript";
private static class ConsummeInputStream
extends Thread
{
private InputStream in;
ConsummeInputStream(InputStream in)
{
this.in=in;
}
#Override
public void run()
{
try
{
int c;
while((c=this.in.read())!=-1)
System.err.print((char)c);
}
catch(IOException err)
{
err.printStackTrace();
}
}
}
TestLoess()
{
}
private void run() throws Exception
{
int num=100;
Random rand=new Random(0L);
double x[]=new double[num];
double y[]=new double[x.length];
for(int i=0;i< x.length;++i)
{
x[i]=rand.nextDouble()+(i>0?x[i-1]:0);
y[i]=Math.sin(i)*100;
}
LoessInterpolator loessInterpolator=new LoessInterpolator(
0.75,//bandwidth,
2//robustnessIters
);
double y2[]=loessInterpolator.smooth(x, y);
Process proc=Runtime.getRuntime().exec(
new String[]{RScript,"-"}
);
ConsummeInputStream errIn=new ConsummeInputStream(proc.getErrorStream());
BufferedReader stdin=new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintStream out=new PrintStream(proc.getOutputStream());
errIn.start();
out.print("T<-as.data.frame(matrix(c(");
for(int i=0;i< x.length;++i)
{
if(i>0) out.print(',');
out.print(x[i]+","+y[i]);
}
out.println("),ncol=2,byrow=TRUE))");
out.println("colnames(T)<-c('x','y')");
out.println("T2<-loess(y ~ x, T)");
out.println("write.table(residuals(T2),'',col.names= F,row.names=F,sep='\\t')");
out.flush();
out.close();
double y3[]=new double[x.length];
for(int i=0;i< y3.length;++i)
{
y3[i]=Double.parseDouble(stdin.readLine());
}
System.out.println("X\tY\tY.java\tY.R");
for(int i=0;i< y3.length;++i)
{
System.out.println(""+x[i]+"\t"+y[i]+"\t"+y2[i]+"\t"+y3[i]);
}
}
public static void main(String[] args)
throws Exception
{
new TestLoess().run();
}
}
compilation & exec:
javac -cp commons-math-2.2.jar TestLoess.java && java -cp commons-math-2.2.jar:. TestLoess
output:
X Y Y.java Y.R
0.730967787376657 0.0 6.624884763714674 -12.5936186703287
0.9715042030481429 84.14709848078965 6.5263049649584 71.9725380029913
1.6089216283982513 90.92974268256818 6.269100654071115 79.839773167581
2.159358633515885 14.112000805986721 6.051308261720918 3.9270340708818
2.756903911313087 -75.68024953079282 5.818424835586378 -84.9176311089431
3.090122310789737 -95.89242746631385 5.689740879461759 -104.617807889069
3.4753114955304554 -27.941549819892586 5.541837854229562 -36.0902352062634
4.460153035730264 65.6986598718789 5.168028655980764 58.9472823439219
5.339335553602744 98.93582466233818 4.840314399516663 93.3329030534449
6.280584733084859 41.21184852417566 4.49531113985498 36.7282165788057
6.555538699120343 -54.40211108893698 4.395343460231256 -58.5812856445538
6.68443584999412 -99.99902065507035 4.348559404444451 -104.039069260889
6.831037507640638 -53.657291800043495 4.295400167908642 -57.5419313320511
6.854275630124528 42.016703682664094 4.286978656933373 38.1564179414478
7.401015387322993 99.06073556948704 4.089252482141094 95.7504087842369
8.365502247999844 65.02878401571168 3.7422883733498726 62.5865641279576
8.469992934250815 -28.790331666506532 3.704793544880599 -31.145867173504
9.095139297716374 -96.13974918795569 3.4805388562453574 -98.0047896609079
9.505935493207435 -75.09872467716761 3.3330472034239405 -76.6664588290508
the output values for y are clearly not the same between R and Java; TheY.R column looks good (it's close to the original Y column). How should I change this in order to get Y.java ~ Y.R ?
You need to change the default values of three input parameters to make the Java and R versions identical:
The Java LoessInterpolator only does linear local polynomial regression, but R supports linear (degree=1), quadratic (degree=2), and a strange degree=0 option. So you need to specify degree=1 in R to be identical to Java.
LoessInterpolator defaults number of iterations DEFAULT_ROBUSTNESS_ITERS=2, but R defaults iterations=4. So you need to set control = loess.control(iterations=X) in R (X is the number of iterations).
LoessInterpolator defaults DEFAULT_BANDWIDTH=0.3 but R defaults span=0.75.
I can't speak for the java implementation, but lowess has a number of parameters which control the bandwidth of the fit. Unless you're fitting with the same control parameters you should expect the results to differ. My recommendation whenever people are smoothing data is to plot the original data as well as the fit, and decide for yourself what control parameters yield your desired tradeoff between fidelity to the data and smoothing (aka noise removal).
There are two problems here. First if you plot the data you are generating it looks almost random and the fit generated by loess in R is very poor e.g.
plot(T$x, T$y)
lines(T$s, T2$fitted, col="blue", lwd=3)
Then in your R script you are writing the residuals not the predictions so in this line
out.println("write.table(residuals(T2),'',
col.names= F,row.names=F,sep='\\t')");
you need to change residuals(T2) to predict(T2) e.g.
out.println("write.table(predict(T2),'',
col.names= F,row.names=F,sep='\\t')");
So it was pure chance in your code example that the first couple of lines of residuals generated by R looked a good fit.
For me if I try fitting with some more appropriate data then Java and R do return similar but not identical results. Also I found the results were closer if I did not adjust the default robustnessIter settings.

Categories