Using the NetLogo API to get turtle coordinates - java

I am trying to get coordinates for turtles in NetLogo by using the Java API. I have managed to get the workspace loaded and have been using the following code that I made:
public static int getX(HeadlessWorkspace workspace, String playerName, int agentNum)
{
Double doubleX = null;
int xVal = 0;
try
{
xVal = doubleX.valueOf((workspace.report("[xcor] of "+playerName+" "+agentNum).toString()).trim()).intValue();
}
catch(Exception ex)
{
ex.printStackTrace();
}
return xVal;
}
However, there is one small problem. It is extremely slow when there are more than 5 turtles. When I run the Flocking code with 200 turtles, without getting the coordinates, then I get about 300 ticks in 10 seconds. When I run the code with the coordinates, then each tick takes about 3 seconds. Is there a more efficient way of achieving this?
Thanks,
Nadim

I managed to find out what the proper way should be. This is the code in the NetLogo mailing list as given by Seth Tisue.
import org.nlogo.headless.*;
import org.nlogo.api.*;
class J {
public static void main(String[] args) {
try {
HeadlessWorkspace ws = HeadlessWorkspace.newInstance();
ws.openString(org.nlogo.util.Utils.url2String("/system/empty.nlogo"));
ws.command("cro 8 [ fd 5 ]");
org.nlogo.api.Turtle turtle =(org.nlogo.api.Turtle) ws.world().turtles().agent(3);
System.out.println("[xcor] of turtle 3 = " + turtle.xcor());
ws.dispose();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
I have reproduced the code here so it may benefit others. To see a list of what information you can get from Turtle, look at the NetLogo API documentation.
Nadim

So, you are using the Java API just so you can get the
[xcor] of "bob" 10
I am very confused.
I can tell you that your workspace.report() call above is very expensive as you are asking netlogo to parse then evaluate the expression you create, then you parse it into an integer to pass back to netlogo.
It seems it would be much easier to just store all the players in a list or map and refer to them by their index in the list. That is, I don't think you need to use the API to do what you seem to be doing.

Related

How to send values through methods

I am stumped trying to send a value through some methods as part of a question which reads
Write the following method: computeDiameter: This method accepts the radius (r) of a circle, and returns it's diameter (2*r)
It's under the "Passing values through different methods", so instead of asking me for a simple variable/formula like
double r;
double diameter = r*2; //along with Scanner and some System out prints
It's asking me to send the value of r through another method, then return the method and print out the new value for r. This is what I have so far
import java.util.*;
public class UserSquares
{
public static void main(String[] args)
{
int r = 2;
int result=0; //I set result=0 hoping to initialize it properly.
computeDiameter(r);
System.out.println(result);
}
public static int computeDiameter(int r)
{
int result = r * 2;
return result;
}
}
This question seemed very simple which is why i tried to tackle it. I know the basics of sending values through a method, but i don't know how to return them. I don't really have money for actual text books (so i settle for quizlet questions and stuff like that), and youtube videos don't help at all so I like coming to the forums to get help when I am really stumped but want to move on with other topics.
(this question is part of a java self test, just thought I should share that as I've asked a number of questions on this site and each time someone responds with something negatively as if I am trying to get you guys to complete my homework for me. I am not taking any Java classes, these questions are just self testing my skills so that when I do major in java programming after i finish highschool, I can have a pretty nice understanding of it. Again, this is not for a test, I am welcome to all types of explanations, as long as it is in the realm of comprehension for a beginner Java student. Please and thank you in advance)
EDIT: Thanks Guys. Immediately after I submitted this I worked on it some more and found a solution so i'll share it
new code
import java.util.*;
public class UserSquares
{
public static void main(String[] args)
{
int total, r = 2;
total = computeDiameter(r);
System.out.println(total);
}
public static int computeDiameter(int value1)
{
int result;
result = value1 * 2;
return result;
}
}
EDIT #2: Holy crap I didn't expect to receive so many solutions so quick. Was about to answer it myself so that it would appear to be done. Sorry for the waste of your time guys, I will read every one of them to see the different solutions you guys offered and learn them so that your time isn't totally wasted. Thanks so much.
EDIT #3: Had a redundant line remaining from my first code that I forgot to take out that went through the compilation and didn't affect the outcome in anyway, but still decided to take it out. Thanks CodeMatrix!
As I said in the comment section.
Go ahead and change this
int result = 0;
computeDiameter(r);
System.out.println(result);
to this
int result = 0; //or you use int result = computeDiameter(r);
result = computeDiameter(r);
System.out.println(result);
its very simple:
int result = computeDiameter(r);
or just
System.out.println(coputeDiameter(r));
You have to assign the value which is being returned from computeDiameter(r) method to the result variable in order to print that.
result = computeDiameter(r);
System.out.println(result);

How to limit characters on a line and make the display go to the next line

I'd like some help with a Java assignment, if it's no problem. We've just been getting started, but my teacher wants us to do a bunch of research on our own and I can't figure out how to do the homework.
We have an assignment where he's given us the lines to 10 different speeches, and we have to use objective oriented coding to display the entire thing. I figured out so far how to set up variables to link to the first file and have things displayed on the screen, but he wants us to limit how many characters are on each line so he doesn't have to scroll sideways forever to read a speech on a single line. This leaves me in a position where I'd be making new variables for every sentence of every speech for the next few hours, and I figure there has to be a more efficient way. So, I asked my friend (who took the class last year) for advice, and he recommended using a for loop to scan for spaces after a certain amount of characters and jump to the next line to continue, but I have no idea how to do any of this. All I have so far is the base file that our teacher told us to use, and the beginning of the first of 10 speeches.
/**
* TextWriter is a program that uses objective coding to display 10 political speeches
* #author ()
* #version (10/12/16)
*/
public class TextWriter {
private String textToDisplay;//text to be displayed
public TextWriter() {
textToDisplay = "";
}
public TextWriter(String inputText) {
textToDisplay = inputText;
}
public void clearTextToDisplay() {
textToDisplay = "";
}
public void setTextToDisplay(String inputText) {
textToDisplay = inputText;
}
public String getTextToDisplay() {
return textToDisplay;
}
public void display() {
System.out.println(textToDisplay);
}
}
and the second one,
/**
* Displays Washington's Farewell speech using objective oriented coding.
* #author ()
* #version (10/12/16)
*/
public class WashingtonFarewellDriver {
public static void main(String[] args) {
TextWriter wf1;
wf1 = new TextWriter();
wf1.setTextToDisplay("Friends and Citizens: The period for a new election of a citizen to administer the executive government of the United States being not far distant, and the time actually arrived when your thoughts must be employed in designating the person who is to be clothed with that important trust, it appears to me proper, especially as it may conduce to a more distinct expression of the public voice, that I should now apprise you of the resolution I have formed, to decline being considered among the number of those out of whom a choice is to be made.");
wf1.display();
TextWriter wf2;
wf2 = new TextWriter("I beg you, at the same time, to do me the justice to be assured that this resolution has not been taken without a strict regard to all the considerations appertaining to the relation which binds a dutiful citizen to his country; and that in withdrawing the tender of service, which silence in my situation might imply, I am influenced by no diminution of zeal for your future interest, no deficiency of grateful respect for your past kindness, but am supported by a full conviction that the step is compatible with both.");
wf2.display();
TextWriter wf3;
wf3 = new TextWriter("The acceptance of, and continuance hitherto in, the office to which your suffrages have twice called me have been a uniform sacrifice of inclination to the opinion of duty and to a deference for what appeared to be your desire. I constantly hoped that it would have been much earlier in my power, consistently with motives which I was not at liberty to disregard, to return to that retirement from which I had been reluctantly drawn.");
wf3.display();
}
}
(hopefully that's formatted right)
I hope that it's ok that I'm asking for homework help, because it does seem to be kind of looked down upon, but I'm pretty confused and hopefully someone can explain what's going on a little more than my teacher.
Thank you! If there's any questions, I might be able to answer them too.
Loop thru the string character by character using String.charAt(). Keep track of how many characters you've put out. After say 25 characters the next time you see a space spit out a newline character, reset your counter to 0, and start printing it out again.
String in = "This is a run on sentence that is too long for a single line and should be broken up into multiple lines because I said so. This is a run on sentence that is too long for a single line and should be broken up into multiple lines because I said so.";
int counter=0;
for(int i=0;i<in.length();i++){
Char c=in.charAt(i);
counter++;
System.out.print(c+"");
if((counter>25)&&(c=' ')){
System.out.println();
counter=0;
}
}
There are many ways to approach this.
You can add this function in your TextWriter class for adding lines something like this:
public void addLines(int maxChars){
int lines = 1;
String[] lineStrings;
if(maxChars <= textToDisplay.length()){
if(textToDisplay.length() % maxChars > 0) lines = textToDisplay.length()/maxChars + 1;
else lines = textToDisplay.length()/maxChars;
lineStrings = new String[lines];
for(int i = 0; i < lines; i++){
if(i == (lines - 1)) lineStrings[i] = textToDisplay.substring(i*maxChars, i*maxChars + (textToDisplay.length() % maxChars)) + "\r\n";
else lineStrings[i] = textToDisplay.substring(i*maxChars, i*maxChars + maxChars) + "\r\n";
}
textToDisplay = "";
for(int i=0; i < lines; i++){
textToDisplay += lineStrings[i];
}
}
}
and in your Main function, maybe:
public class WashingtonFarewellDriver {
public static void main(String[] args) {
TextWriter wf1;
wf1 = new TextWriter();
wf1.setTextToDisplay("Friends and Citizens: The period for a new election of a citizen to administer the executive government of the United States being not far distant, and the time actually arrived when your thoughts must be employed in designating the person who is to be clothed with that important trust, it appears to me proper, especially as it may conduce to a more distinct expression of the public voice, that I should now apprise you of the resolution I have formed, to decline being considered among the number of those out of whom a choice is to be made.");
wf1.addLines(50);
wf1.display();
TextWriter wf2;
wf2 = new TextWriter("I beg you, at the same time, to do me the justice to be assured that this resolution has not been taken without a strict regard to all the considerations appertaining to the relation which binds a dutiful citizen to his country; and that in withdrawing the tender of service, which silence in my situation might imply, I am influenced by no diminution of zeal for your future interest, no deficiency of grateful respect for your past kindness, but am supported by a full conviction that the step is compatible with both.");
wf2.addLines(50);
wf2.display();
TextWriter wf3;
wf3 = new TextWriter("The acceptance of, and continuance hitherto in, the office to which your suffrages have twice called me have been a uniform sacrifice of inclination to the opinion of duty and to a deference for what appeared to be your desire. I constantly hoped that it would have been much earlier in my power, consistently with motives which I was not at liberty to disregard, to return to that retirement from which I had been reluctantly drawn.");
wf3.addLines(50);
wf3.display();
}
}
This should work, but some words will be cut off, because this just roughly separates lines by a maximum characters in a line.
thanks for all the feedback, it helped me, but ultimately there was another pretty easy way my that friend walked me through using the main.org.apache.commons.lang3.text.WordUtils package that he downloaded!
import java.io.IOException;
import org.apache.commons.lang3.text.WordUtils;
public class WashingtonFarewellDriver {
public static void main(String[] args) throws IOException {
int wwl = 110;
TextWriter wf1;
wf1 = new TextWriter(WordUtils.wrap("long sentences",wwl));
wf1.display();
}
}

Weka in Java - How to get predictions for IBk or KStar or LWL or

I've searched all over stackoverflow and google for these kind predicitons but found nothing for IBk or KStar or LWL. I would need one instance predictions from any of these three clasifiers.I am doing this in Android studio.
I've found ways of getting predictions from other classifiers like these:
for J48: from Here
double[] prediction=j48.distributionForInstance(test.get(s1));
//output predictions
for(int i=0; i<prediction.length; i=i+1)
{
System.out.println("Probability of class "+
test.classAttribute().value(i)+
" : "+Double.toString(prediction[i]));
}
For Bayesnet: from Here
Evaluation eTest = new Evaluation(trainingInstance);
eTest.evaluateModelOnce(bayes_Classifier, testInstance);
For NaiveBayes: from Here
NaiveBayes naiveBayes = new NaiveBayes();
naiveBayes.buildClassifier(train);
// this does the trick
double label = naiveBayes.classifyInstance(test.instance(0));
test.instance(0).setClassValue(label);
System.out.println(test.instance(0).stringValue(4));
but I couldn't use them because my classifiers don't have the same methods...or I can't find a way
My code:
//I skipped code till here because its too much,
//but Data is definetly inside *instances* (I checked with debuger)
instances.setClassIndex(instances.numAttributes()-1);
//was trying the sam with KStar, LWL, AdditiveRegression, RandomCommittee)
IBk ibk = new IBk();
//I want predicitons for this instance. For the third attribute3
Instance testInst = new DenseInstance(3);
testInst.setValue(attribute1, 3);
testInst.setValue(attribute2, 16);
testInst.setValue(attribute3, 0);
//I was hopping for some simple way like this: (but this returns nothing)
double rez =0;
String var="";
try{
ibk.buildClassifier(instances);
rez = ibk.classifyInstance(testInst);
}
catch(Exception ex)
{
Log.e("Error","ex.getMessage()");
}
}
Log.w("GIMME RESULTS:",rez);
Even other classifiers would be okay like AdditiveRegression, Bagging, RandomCommitte and DecisionTable they make good prediction in Weka GUI, but I need predictions in Java.... :)
found it by testing all its methods..
ibk.buildClassifier(dataSet);
rez2 = ibk.distributionForInstance(i2); //distrib
int result = (int)rez3[0];
//it goes tha same with Kstar
Came to realize that classifiers in weka normaly run with discrete data (equal steps from min to max). And my data is not all discrete. Ibk and Kstar are able to use distributed data thats why I can use only these two with my data.

Simulate counting over N sensors with java

I need to simulate in Java N sensors that send to me an obsvertation at random time. Where an observation contain more value like:
timestamp - temperature - umiditiy - ...
When i receive an observation from anyone (the time of observation is random for all sensor) of the N sensors i need to call a rutine R that refresh a data structure (in common between all sensors) with some counting.
I need to syncronyze the R call, if i call R first time for call R second time i need R first time to finish his work.
All my observation are actually stored in a CSV file, one file for sensor. But i need to simulate a "online streaming".
How i can make that in Java? If i make N threads (one for sensor) that read his CSV file, i can't read the observation in right temporal order over all CSV.
For example, if i have this 2 csv:
Csv1:
18:00 - low - low
19:00 - low - high
Csv2
18:03 - high - low
I need first to refresh my counting with obsvervation at time 18:00 in csv1, then with obsvervation at time 18:0 in csv2 and finally with observation at time 19:00 in csv2.
EDIT1: I have make a test with SynchronousQueue because I need to syncronyze my N thread, my problem is when one thread do something on counting structure other thread can't access to it.
I have find this example:
package threadTest;
import java.util.concurrent.SynchronousQueue;
public class SynchronousQueueTest
{
private SynchronousQueue sq = new SynchronousQueue(true);
class PutThread implements Runnable
{
public void run()
{
for(int i=0; i <1000; i++)
{
try {
System.out.println("PUT");
//sq.put("A");
sq.put("A");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class TakeThread implements Runnable
{
public void run()
{
for(int i=0; i <1000; i++)
{
try {
System.out.println("TAKE");
System.out.println(sq.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args)
{
new Thread((new SynchronousQueueTest()).new PutThread()).start();
new Thread((new SynchronousQueueTest()).new TakeThread()).start();
}
}
But i have not the expected result. The output is only this:
PUT
TAKE
But i'm expected 1000 PUT and 1000 TAKE alternate. What is the problem?
Ha. That sounds so much like what I do usually when preparing stock tick data for back test.
Normally you massage the CSV files to be at least internally time ordered. Then you can either read them and combine at beginning - or if you have multiple readers you need to put the data into a PriorityQueue based structure, say, DelayQueue. Have your simulation data structure wrap the actual data and implement Delayed interface so you know how much delay you need. This is all you need from reading side.
From publishing side, use just 1 thread and publish to the time you needed - then schedule the next round with delay like 1ms or so. That's usually enough.
From subscriber side, the subscriber is blind and just take the data as if it's from real.
BTW, if you are really doing back testing or so, you might want to write up your own time service class which can simulate a faster tick of the data.

Echo/delay algorithm just causes noise/static?

There have been other questions and answers on this site suggesting that, to create an echo or delay effect, you need only add one audio sample with a stored audio sample from the past. As such, I have the following Java class:
public class DelayAMod extends AudioMod {
private int delay = 500;
private float decay = 0.1f;
private boolean feedback = false;
private int delaySamples;
private short[] samples;
private int rrPointer;
#Override
public void init() {
this.setDelay(this.delay);
this.samples = new short[44100];
this.rrPointer = 0;
}
public void setDecay(final float decay) {
this.decay = Math.max(0.0f, Math.min(decay, 0.99f));
}
public void setDelay(final int msDelay) {
this.delay = msDelay;
this.delaySamples = 44100 / (1000/this.delay);
System.out.println("Delay samples:"+this.delaySamples);
}
#Override
public short process(short sample) {
System.out.println("Got:"+sample);
if (this.feedback) {
//Delay should feed back into the loop:
sample = (this.samples[this.rrPointer] = this.apply(sample));
} else {
//No feedback - store base data, then add echo:
this.samples[this.rrPointer] = sample;
sample = this.apply(sample);
}
++this.rrPointer;
if (this.rrPointer >= this.samples.length) {
this.rrPointer = 0;
}
System.out.println("Returning:"+sample);
return sample;
}
private short apply(short sample) {
int loc = this.rrPointer - this.delaySamples;
if (loc < 0) {
loc += this.samples.length;
}
System.out.println("Found:"+this.samples[loc]+" at "+loc);
System.out.println("Adding:"+(this.samples[loc] * this.decay));
return (short)Math.max(Short.MIN_VALUE, Math.min(sample + (int)(this.samples[loc] * this.decay), (int)Short.MAX_VALUE));
}
}
It accepts one 16-bit sample at a time from an input stream, finds an earlier sample, and adds them together accordingly. However, the output is just horrible noisy static, especially when the decay is raised to a level that would actually cause any appreciable result. Reducing the decay to 0.01 barely allows the original audio to come through, but there's certainly no echo at that point.
Basic troubleshooting facts:
The audio stream sounds fine if this processing is skipped.
The audio stream sounds fine if decay is 0 (nothing to add).
The stored samples are indeed stored and accessed in the proper order and the proper locations.
The stored samples are being decayed and added to the input samples properly.
All numbers from the call of process() to return sample are precisely what I would expect from this algorithm, and remain so even outside this class.
The problem seems to arise from simply adding signed shorts together, and the resulting waveform is an absolute catastrophe. I've seen this specific method implemented in a variety of places - C#, C++, even on microcontrollers - so why is it failing so hard here?
EDIT: It seems I've been going about this entirely wrong. I don't know if it's FFmpeg/avconv, or some other factor, but I am not working with a normal PCM signal here. Through graphing of the waveform, as well as a failed attempt at a tone generator and the resulting analysis, I have determined that this is some version of differential pulse-code modulation; pitch is determined by change from one sample to the next, and halving the intended "volume" multiplier on a pure sine wave actually lowers the pitch and leaves volume the same. (Messing with the volume multiplier on a non-sine sequence creates the same static as this echo algorithm.) As this and other DSP algorithms are intended to work on linear pulse-code modulation, I'm going to need some way to get the proper audio stream first.
It should definitely work unless you have significant clipping.
For example, this is a text file with two columns. The leftmost column is the 16 bit input. The second column is the sum of the first and a version delayed by 4001 samples. The sample rate is 22KHz.
Each sample in the second column is the result of summing x[k] and x[k-4001] (e.g. y[5000] = x[5000] + x[999] = -13840 + 9181 = -4659) You can clearly hear the echo signal when playing the samples in the second column.
Try this signal with your code and see if you get identical results.

Categories

Resources