I wanted to make a Java app that calculates the square root using the Heron algorithm. But when I enter 9 it prints 2.777777910232544 to the screen.
When I enter 1 it prints 1. Now I do not know if I wrote the wrong code or I don't know something about floats in Java.
Here is my code:
public class MainActivity extends AppCompatActivity {
float length1;
float width1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView mainOutput = (TextView) findViewById(R.id.mainOutput);
final EditText mainInput = (EditText) findViewById(R.id.mainInput);
final Button wurzel2 = (Button) findViewById(R.id.wurzel2);
assert wurzel2 != null;
wurzel2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
for(int i = 0; i < 20; i++) {
float inputNumber = Integer.parseInt(mainInput.getText().toString());
length1 = 1;
width1 = inputNumber / length1;
float length2 = (length1 + width1) / 2;
float width2 = inputNumber / length2;
length1 = length2;
width1 = width2;
}
double wurzel = length1 / width1;
mainOutput.setText(String.valueOf(wurzel));
}
});
}
}
I wrote a non-Android Java implementation of Heron's algorithm derived from the formula for the algorithm displayed at https://en.wikipedia.org/wiki/Methods_of_computing_square_roots
public class MyClass {
public static void main(String[] args) {
float x = 9;
System.out.println(heron(x));
}
static float heron(float s) {
float x = (float) 1.0; // initial approximation of result
for (int i = 0; i < 20; i++) {
float sDivX = s / x;
x = (x + sDivX) / 2;
// remove this line in production, this is just to watch progress
System.out.println(String.valueOf(x));
}
return x;
}
}
Your code had length1=1 (your length1 is equivalent to my x) inside the loop, so
it made no progress from iteration to iteration.
x = s/(float)2 might be a better initial estimate than 1, especially for larger values. 20 iterations is probably overkill for smallish values of the input value.
I make my first steps in implementation of batch and stochastic gradient descent.
Here is my implementation:
package ch.learning;
import java.util.*;
import org.jzy3d.analysis.AbstractAnalysis;
import org.jzy3d.analysis.AnalysisLauncher;
import org.jzy3d.chart.factories.AWTChartComponentFactory;
import org.jzy3d.colors.Color;
import org.jzy3d.colors.ColorMapper;
import org.jzy3d.colors.colormaps.ColorMapRainbow;
import org.jzy3d.maths.Coord3d;
import org.jzy3d.maths.Range;
import org.jzy3d.plot3d.builder.*;
import org.jzy3d.plot3d.builder.concrete.*;
import org.jzy3d.plot3d.primitives.Scatter;
import org.jzy3d.plot3d.primitives.Shape;
import org.jzy3d.plot3d.rendering.canvas.Quality;
import org.apache.commons.math3.analysis.function.Sigmoid;
public class LogisticReg_GradientDescent {
private List<double[]> trainingExamples = new LinkedList<double[]>();
private static final int sizeTrainingset = 1000;
private volatile double[] theta = {10, 10, 10, 10 };
// Configurable compoenent of step size during theata update
private final double alpha = 0.01;
// Amount of iteration in Batch Gradient Descent
private static final int iterations = 10000;
private static final int printsAtStartAndEnd = 5;
private void buildTrainingExample(int amount) {
// Area of the house
double areaMin = 80;
double areaMax = 1000;
double areaRange = areaMax - areaMin;
// Distance to center
double distanceMin = 10;
double distanceMax = 10000;
double distanceRange = distanceMax - distanceMin;
// Generate training examples with prices
for (int i = 0; i < amount; i++) {
double[] example = new double[5];
example[0] = 1.0;
example[1] = areaMin + Math.random() * areaRange;
example[2] = distanceMin + Math.random() * distanceRange;
// Price is a feature as well in this logistic regression example
double price = 0;
price += _priceComponent(example[1], areaRange);
price += _priceComponent(example[2], distanceRange);
// price += _priceComponent(example[3], yocRange);
example[3] = price;
example[4] = (price>200000)?0:1;
trainingExamples.add(example);
}
}
// Random price according with some range constraints
private double _priceComponent(double value, double range) {
if (value <= range / 3)
return 50000 + 50000 * Math.random() * 0.1;
if (value <= (range / 3 * 2))
return 100000 + 100000 * Math.random() * 0.1;
return 150000 + 150000 * Math.random() * 0.1;
}
private double classificationByHypothesis(double[] features) {
// Scaling
double scalingF0 = features[0];
double scalingF1 = (features[1] - 80) / (920);
double scalingF2 = (features[2] - 10) / (9990);
double scalingF3 = (features[3] - 50000) / (400000);
double z = this.theta[0] * scalingF0 + this.theta[1] * scalingF1 + this.theta[2] * scalingF2
+ this.theta[3] * scalingF3;
double ret = 1 / (1 + Math.pow(Math.E, -z));
return ret;
}
// Costfunction: Mean squared error function
private double gradientBatch_costs() {
double costs = this.trainingExamples.stream().mapToDouble(l -> {
double costsint;
if (l[4] == 0) {
costsint = -Math.log(1 - classificationByHypothesis(l));
} else {
costsint = -Math.log(classificationByHypothesis(l));
}
return costsint;
}).sum();
return costs / this.trainingExamples.size();
}
// Theta Update with Batch Gradient Descent
private void gradientBatch_thetaUpdate(int amount) {
for (int i = 0; i < amount; i++) {
double partialDerivative0 = this.trainingExamples.stream()
.mapToDouble(l -> (classificationByHypothesis(l) - l[4]) * l[0]).sum();
double tmpTheta0 = this.theta[0] - (this.alpha * partialDerivative0 / this.trainingExamples.size());
double partialDerivative1 = this.trainingExamples.stream()
.mapToDouble(l -> (classificationByHypothesis(l) - l[4]) * l[1]).sum();
double tmpTheta1 = this.theta[1] - (this.alpha * partialDerivative1 / this.trainingExamples.size());
double partialDerivative2 = this.trainingExamples.stream()
.mapToDouble(l -> (classificationByHypothesis(l) - l[4]) * l[2]).sum();
double tmpTheta2 = this.theta[2] - (this.alpha * partialDerivative2 / this.trainingExamples.size());
double partialDerivative3 = this.trainingExamples.stream()
.mapToDouble(l -> (classificationByHypothesis(l) - l[4]) * l[3]).sum();
double tmpTheta3 = this.theta[3] - (this.alpha * partialDerivative3 / this.trainingExamples.size());
this.theta = new double[] { tmpTheta0, tmpTheta1, tmpTheta2, tmpTheta3 };
}
}
// Theta update with Stochastic Gradient Descent
private void gradientStochastic_thetaUpdate(double[] feature) {
double tmpTheta0 = this.theta[0] - this.alpha * (classificationByHypothesis(feature) - feature[4]) * feature[0];
double tmpTheta1 = this.theta[1] - this.alpha * (classificationByHypothesis(feature) - feature[4]) * feature[1];
double tmpTheta2 = this.theta[2] - this.alpha * (classificationByHypothesis(feature) - feature[4]) * feature[2];
double tmpTheta3 = this.theta[3] - this.alpha * (classificationByHypothesis(feature) - feature[4]) * feature[3];
this.theta = new double[] { tmpTheta0, tmpTheta1, tmpTheta2, tmpTheta3 };
}
private void resetTheta() {
this.theta = new double[] {0.00001, 0.00001, 0.00001, 0.00001};
}
private void printSummary(int iteration) {
System.out.println(String.format("%s \t\t Theta: %f \t %f \t %f \t %f \t Costs: %f", iteration, this.theta[0],
this.theta[1], this.theta[2], this.theta[3], this.gradientBatch_costs()));
}
public static void main(String[] args) {
LogisticReg_GradientDescent d = new LogisticReg_GradientDescent();
// Batch and Stochastic Gradient Descent use the same training example
d.buildTrainingExample(sizeTrainingset);
System.out.println("Batch Gradient Descent");
d.printSummary(0);
System.out.println(String.format("First %s iterations", printsAtStartAndEnd));
for (int i = 1; i <= iterations; i++) {
d.gradientBatch_thetaUpdate(1);
d.printSummary(i);
}
System.out.println("Some examples are:");
System.out.println(String.format("The 1:%s, Area:%s, Distance:%s, Price:%s, Classification:%s", d.trainingExamples.get(0)[0],d.trainingExamples.get(0)[1],d.trainingExamples.get(0)[2],d.trainingExamples.get(0)[3],d.trainingExamples.get(0)[4]));
System.out.println(String.format("The 1:%s, Area:%s, Distance:%s, Price:%s, Classification:%s", d.trainingExamples.get(500)[0],d.trainingExamples.get(500)[1],d.trainingExamples.get(500)[2],d.trainingExamples.get(500)[3],d.trainingExamples.get(500)[4]));
try {
AnalysisLauncher.open(d.new SurfaceDemo());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class SurfaceDemo extends AbstractAnalysis{
#Override
public void init(){
double x;
double y;
double z;
float a;
Coord3d[] points = new Coord3d[trainingExamples.size()];
Color[] colors = new Color[trainingExamples.size()];
for(int i=0; i<trainingExamples.size(); i++){
x = trainingExamples.get(i)[1]; // Area
y = trainingExamples.get(i)[2]; // Distance to center
z = trainingExamples.get(i)[3]; // price
points[i] = new Coord3d(x, y, z);
a = 1f;
if(trainingExamples.get(i)[4]==1){
colors[i] =new Color(0,0,0,a);
}else{
colors[i]= new Color(250,0,0,a);
}
}
Scatter scatter = new Scatter(points, colors);
scatter.setWidth(4);
Mapper mapper = new Mapper() {
#Override
public double f(double x, double y) {
return (-theta[0]-theta[1]*x-theta[2]*y)/theta[3];
}
};
// Create the object to represent the function over the given range.
Range rangeX = new Range(0, 1000);
Range rangeY = new Range(0, 10000);
int steps = 10;
final Shape surface = Builder.buildOrthonormal(new OrthonormalGrid(rangeX, steps, rangeY, steps), mapper);
surface.setColorMapper(new ColorMapper(new ColorMapRainbow(), surface.getBounds().getZmin(), surface.getBounds().getZmax(), new Color(1, 1, 1, .5f)));
surface.setFaceDisplayed(true);
surface.setWireframeDisplayed(false);
chart = AWTChartComponentFactory.chart(Quality.Advanced, getCanvasType());
chart.getScene().add(scatter);
chart.getScene().add(surface);
}
}
}
A graphical representation looks like
So i plot the generated training instances with org.jzy3d.plot3d.
We see x(the area of the house), y(distance to town center) and z(price).
The classification makes red (negative class -> not sold) and black (positive class -> sold).
In the generated trainings instances the classification depends just at the price, you see it here:
example[4] = (price>200000)?0:1;
The problem, the thing I don't understand is
I would like to plot the decision boundary of my classificator.
The decision bounday depends on the optimized components from Theta. (Using batch gradient descent).
So i try to plot the decision boundary plane with this code:
Mapper mapper = new Mapper() {
#Override
public double f(double x, double y) {
return (-theta[0]-theta[1]*x-theta[2]*y)/theta[3];
}
};
Because
theta[0]*1 + theta[1 ]*x + theta[2]*y + theta[3]*z = 0
so
z = -(theta[0]*1 + theta[1 ]*x + theta[2]*y)/theta[3]
I would expect my decision boundary plane between the red- and blackarea.
Instead it hangs around by z=0.
I didn't know, either I'm not able to plot this decision boundary plane in a proper way, or my optimized parameters are shit.
Further I don't know how to choose a good initial theta vector.
Right now i use
private volatile double[] theta = {1, 1, 1, 1 };
I set alpha to 0.0001
private final double alpha = 0.0001;
It was the biggest possible Alpha, where my cost function doesn't jump around and the sigmoid implementation doesn't return infinity.
I already make feature scaling at
private double classificationByHypothesis(double[] features) {
// Scaling
double scalingF0 = features[0];
double scalingF1 = (features[1] - 80) / (920);
double scalingF2 = (features[2] - 10) / (9990);
double scalingF3 = (features[3] - 50000) / (400000);
double z = this.theta[0] * scalingF0 + this.theta[1] * scalingF1 + this.theta[2] * scalingF2
+ this.theta[3] * scalingF3;
double ret = 1 / (1 + Math.pow(Math.E, -z));
return ret;
}
The last five iteration with given initial theta and alpha equals 0.0001 are
9996,Theta: 1.057554,-6.340981,-6.242139,8.145087,Costs: 0.359108
9997,Theta: 1.057560,-6.341234,-6.242345,8.145576,Costs: 0.359109
9998,Theta: 1.057565,-6.341487,-6.242552,8.146065,Costs: 0.359110
9999,Theta: 1.057571,-6.341740,-6.242758,8.146553,Costs: 0.359112
10000,Theta: 1.057576,-6.341993,-6.242965,8.147042,Costs: 0.359113
Some example of the generated training instances are
Area: 431.50139030510206, Distance: 8591.341686012887,
Price: 255049.1280388437, Classification:0.0
Area: 727.4042972310916, Distance: 4364.710136408952,
Price: 258385.59452489938, Classification:0.0
Thanks for any hint!
I am making an application for teachers that you put in the max number of points and it tells you the percent of each amount wrong. I then would like to use that percentage to make each of the textviews display the grade with the corresponding percentage. So the first column is the amount right out of the max, the second column is the percentage, and the third column is the letter grade. I then have eight rows, but would like to expand that in the future. I know that I would have to an if to say if the percent is between two numbers, settext to a letter grade, but would I have to do the same for every textview, or what other way would there be to do this?
This is the code for what I basically have to far:
MaxInt = Integer.parseInt(number);
minus1 = MaxInt - 1;
minus2 = MaxInt - 2;
minus3 = MaxInt - 3;
minus4 = MaxInt - 4;
minus5 = MaxInt - 5;
minus6 = MaxInt - 6;
minus7 = MaxInt - 7;
minus8 = MaxInt - 8;
float PD1 = (minus1 * 100.0f) / MaxInt;
float PD2 = (minus2 * 100.0f) / MaxInt;
float PD3 = (minus3 * 100.0f) / MaxInt;
float PD4 = (minus4 * 100.0f) / MaxInt;
float PD5 = (minus5 * 100.0f) / MaxInt;
float PD6 = (minus6 * 100.0f) / MaxInt;
float PD7 = (minus7 * 100.0f) / MaxInt;
float PD8 = (minus8 * 100.0f) / MaxInt;
int D1 = (int) PD1;
int D2 = (int) PD2;
int D3 = (int) PD3;
int D4 = (int) PD4;
int D5 = (int) PD5;
int D6 = (int) PD6;
int D7 = (int) PD7;
int D8 = (int) PD8;
P1 = String.valueOf(D1);
P2 = String.valueOf(D2);
P3 = String.valueOf(D3);
P4 = String.valueOf(D4);
P5 = String.valueOf(D5);
P6 = String.valueOf(D6);
P7 = String.valueOf(D7);
P8 = String.valueOf(D8);
TV1.setText(Integer.toString(minus1));
TV2.setText(Integer.toString(minus2));
TV3.setText(Integer.toString(minus3));
TV4.setText(Integer.toString(minus4));
TV5.setText(Integer.toString(minus5));
TV6.setText(Integer.toString(minus6));
TV7.setText(Integer.toString(minus7));
TV8.setText(Integer.toString(minus8));
TV9.setText(P1 + "%");
TV10.setText(P2 + "%");
TV11.setText(P3 + "%");
TV12.setText(P4 + "%");
TV13.setText(P5 + "%");
TV14.setText(P6 + "%");
TV15.setText(P7 + "%");
TV16.setText(P8 + "%");
I know that some of that isn't nessesary like converting the float to a integer, then string, but I will fix that when I am done. TV17 - TV24 will be the letter grades.
This is my current code:
public class Sunpos {
final private double Pi = Math.PI;
final private double eul = 2.71828182845904523552 ;
final private double sonauf = 90;
final private double RAD = 0.017453292519943295769236907684886;
public double sunrisefinal (double Breitengrad, double Laengengrad, int tagzahl, int sommerzeit, int nacht) {
double lngHour = Laengengrad/15;
double t = tagzahl + ((6 - lngHour)/24);
// double ab = tagzahl + ((18 - lngHour)/24);
double M = (0.9856 * t) - 3.289;
double L = M + (1.916 * Math.sin(M)) + (0.020 * Math.sin(2 * M)) + 282.634;
if (L >= 359) { L -= 360; }
else if (L < 0) { L += 360; }
double RA = (Math.atan(0.91764 * Math.tan(Pi/180)*L));
if (RA >= 359) { RA -= 360; }
else if (RA < 0) { RA += 360; }
double Lquadrant = (Math.floor(L/90)*90);
double RAquadrant = (Math.floor(RA/90))*90;
RA = RA + (Lquadrant - RAquadrant);
RA = RA/15;
double sinDec = 0.39782 * Math.sin((Pi/180)*L);
double cosDec = (180/Pi)*(Math.cos(Math.asin(sinDec)));
double cosH = (Math.cos((Pi/180)*sonauf)-(sinDec*Math.sin((Pi/180)*Breitengrad)))/(cosDec * Math.cos((Pi/180)*Breitengrad));
double H = 360 - Math.acos(cosH);
H /= 15;
double T = H + RA -(0.06571 * t) - 6.622;
double UTC = T - lngHour;
if (UTC >= 23) { UTC -= 24; }
else if (UTC < 0) { UTC += 24; }
double locTime = UTC; // Fuer die schweiz!
System.out.println(locTime);
return(0);
}
The inputs are the following: ( 50, 10, 294, 1, 0). The last 2 can be ignored.
Now I am basing this on the following page:
http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
The code should be complete according to the site, but I don't get anywhere near the supposed results. I should get around 7.5 for today but I'm getting a 9.358.
Now, that might be because something with radiants/degrees? I can't quite get my Mind into that, as I've been trying to insert those converters (Pi/180) into the code, without any usable result.
Can anyone tell me where to put them or point me in the right direction? I've spent waaaay too much time on this already, and now I'm so close.
I'll just post my implementation here in case people need it (ported from the same source as yours)
https://gist.github.com/zhong-j-yu/2232343b14a5b5ef5b9d
public class SunRiseSetAlgo
{
static double calcSunrise(int dayOfYear, double localOffset, double latitude, double longitude)
{
return calc(dayOfYear, localOffset, latitude, longitude, true);
}
static double calcSunset(int dayOfYear, double localOffset, double latitude, double longitude)
{
return calc(dayOfYear, localOffset, latitude, longitude, false);
}
// http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
static double calc(int dayOfYear, double localOffset, double latitude, double longitude, boolean rise)
{
//1. first calculate the day of the year
// int N1 = floor(275 * month / 9.0);
// int N2 = floor((month + 9) / 12.0);
// int N3 = (1 + floor((year - 4 * floor(year / 4.0) + 2) / 3.0));
// int N = N1 - (N2 * N3) + day - 30;
int N = dayOfYear;
//2. convert the longitude to hour value and calculate an approximate time
double lngHour = longitude / 15;
double t = rise?
N + (( 6 - lngHour) / 24) :
N + ((18 - lngHour) / 24);
//3. calculate the Sun's mean anomaly
double M = (0.9856 * t) - 3.289;
//4. calculate the Sun's true longitude
double L = M + (1.916 * sin(M)) + (0.020 * sin(2 * M)) + 282.634;
L = mod(L, 360);
//5a. calculate the Sun's right ascension
double RA = atan(0.91764 * tan(L));
RA = mod(RA, 360);
//5b. right ascension value needs to be in the same quadrant as L
double Lquadrant = (floor( L/90)) * 90;
double RAquadrant = (floor(RA/90)) * 90;
RA = RA + (Lquadrant - RAquadrant);
//5c. right ascension value needs to be converted into hours
RA = RA / 15;
//6. calculate the Sun's declination
double sinDec = 0.39782 * sin(L);
double cosDec = cos(asin(sinDec));
//7a. calculate the Sun's local hour angle
double zenith = 90 + 50.0/60;
double cosH = (cos(zenith) - (sinDec * sin(latitude))) / (cosDec * cos(latitude));
if (cosH > 1)
throw new Error("the sun never rises on this location (on the specified date");
if (cosH < -1)
throw new Error("the sun never sets on this location (on the specified date");
//7b. finish calculating H and convert into hours
double H = rise?
360 - acos(cosH) :
acos(cosH);
H = H / 15;
//8. calculate local mean time of rising/setting
double T = H + RA - (0.06571 * t) - 6.622;
//9. adjust back to UTC
double UT = T - lngHour;
//10. convert UT value to local time zone of latitude/longitude
double localT = UT + localOffset;
localT = mod(localT, 24);
return localT;
}
static int floor(double d){ return (int)Math.floor(d); }
static double sin(double degree)
{
return Math.sin(degree*Math.PI/180);
}
static double cos(double degree)
{
return Math.cos(degree*Math.PI/180);
}
static double tan(double degree)
{
return Math.tan(degree*Math.PI/180);
}
static double atan(double x)
{
return Math.atan(x) *180/Math.PI;
}
static double asin(double x)
{
return Math.asin(x) *180/Math.PI;
}
static double acos(double x)
{
return Math.acos(x) *180/Math.PI;
}
static double mod(double x, double lim)
{
return x - lim * floor(x/lim);
}
}
Everone seems to link to this http://williams.best.vwh.net/sunrise_sunset_algorithm.htm
which doesn't exist anymore. Why not try something that gets updated once in a while like https://en.wikipedia.org/wiki/Sunrise_equation
Then if you like you could help edit it to make it better.
Quick note, I am new to programming Android applications so feel free to say I'm going about this the entirely wrong way or even to explain things to me like I'm an idiot.
My application is very location dependent. I am using the Google Play Location Services to provide the users current location. Users can store locations in their device which I store using a hashmap. In order to make it more convenient I am trying to make it so the user only has to be within a range of that stored location. My current method to create this range is to essentially use a for loop to scan the user's current location to see if it is in the hashmap.
public String scan(Location local) {
String fLoc = "";
List<String> pLoc = new ArrayList<String>();
String loc = "";
double lat = local.getLatitude();
double lon = local.getLongitude();
lat = (double) Math.round(lat * decimal) / decimal;
lon = (double) Math.round(lon * decimal) / decimal;
for (double x = -8; x < 9; x++) {
double tlat = lat;
double tlon = lon;
tlat = tlat + (x / decimal);
tlat = (double) Math.round(tlat * decimal) / decimal;
for (double y = -8; y < 9; y++) {
tlon = lon;
tlon = tlon + (y / decimal);
tlon = (double) Math.round(tlon * decimal) / decimal;
loc = ("Latitude: " + tlat + " Longitude: " + tlon);
if (locMap.containsKey(loc)) {
pLoc.add(loc);
}
}
}
if (pLoc.isEmpty()) {
lat = local.getLatitude();
lon = local.getLongitude();
lat = (double) Math.round(lat * decimal) / decimal;
lon = (double) Math.round(lon * decimal) / decimal;
loc = ("Latitude: " + lat + " Longitude: " + lon);
fLoc = loc;
} else if (pLoc.size() == 1) {
fLoc = (String) pLoc.toArray()[0];
} else {
Double diff = 0.0;
Double tdiff = 10.0;
for (String l : pLoc) {
diff = 10.0;
String[] parts = l.split(" ");
double dlat = Double.parseDouble(parts[1]) - lat;
if (dlat < 0) {
dlat = dlat * -1;
}
double dlon = Double.parseDouble(parts[5]) - lon;
if (dlon < 0) {
dlon = dlon * -1;
}
diff = dlon + dlat;
if (diff < tdiff) {
tdiff = diff;
fLoc = l;
}
}
}
return fLoc;
}
If no location is close, the user's current location is returned. I feel this is a crude method that is wasteful. What is a better way to find nearby locations? Maybe a for loop through saved location to see if the difference between it and the nearby location is small enough, but this could get costly when the user starts save lots of locations.
Any suggestions?
PS Any tips on adding accurate elevation without barometers?