Variable is not passing by - java

I am trying to pass aF variable. But when debugging, it shows to have a value of 0. Any idea? below is the code I am using (Update: I included the whole code).
import java.util.ArrayList;
import java.util.List;
public class EOS {
//defining constants, input variables
public static final double GAS_CONSTANT = 8.3144598; //J K-1 mol-1
double criticalTemperature;
double criticalPressure;
double temperature;
double pressure;
double molecularWeight;
public EOS(double criticalTemperature, double criticalPressure, double temperature, double pressure, double molecularWeight) {
this.criticalTemperature = criticalTemperature;
this.criticalPressure = criticalPressure;
this.temperature = temperature;
this.pressure = pressure;
this.molecularWeight = molecularWeight;
}
// calculation of A* and B* (values of "a" and "b" will be provided by subclasses)
public double aStar(double a) {
return a * pressure / (Math.pow(GAS_CONSTANT, 2) * Math.pow(temperature, 2));
}
public double bStar(double b) {
return b * pressure / (GAS_CONSTANT * temperature);
}
//calculation of Z Value. The idea is to form the cubic function of Z as follow:
public List<Double> calculateZ(double aStar, double bStar, double uValue, double wValue) {
List<Double> solution = new ArrayList<>();
double a, b, c, q, r, d;
a = -1 - bStar + uValue * bStar;
b = aStar + wValue * Math.pow(bStar, 2) - uValue * bStar - uValue * Math.pow(bStar, 2);
c = - bStar * aStar - wValue * Math.pow(bStar, 2) - wValue * Math.pow(bStar, 3);
q = (3*b-Math.pow(a, 2))/3;
r = (2*Math.pow(a, 3)-9*a*b+27*c)/27;
d = (Math.pow(q, 3)/27) + (Math.pow(r, 2)/4);
if (d == 0) {
double x1 = 2*Math.pow(-r/2, 1/3) -(a/3);
double x2 = -2*Math.pow(-r/2, 1/3) -(a/3);
double x3 = x2;
double[] temp = {x1, x2, x3};
for (int i = 0; i < temp.length; i++) {
if (temp[i] > 0) {
solution.add(temp[i]);
}
}
} else if (d > 0) {
double x1 = Math.pow((-r/2)+Math.pow(d, 0.5),1/3)+Math.pow((-r/2)+Math.pow(d, 0.5),1/3)-(a/3);
solution.add(x1);
} else {
double theta = Math.acos((3*r/(2*q))*Math.sqrt(-3/q));
double x1 = 2*Math.sqrt(-q/3)*Math.cos(theta/3)-(a/3);
double x2 = 2*Math.sqrt(-q/3)*Math.cos((theta+2*Math.PI)/3)-(a/3);
double x3 = 2*Math.sqrt(-q/3)*Math.cos((theta+4*Math.PI)/3)-(a/3);
double[] temp = {x1, x2, x3};
for (int i = 0; i < temp.length; i++) {
if (temp[i] > 0) {
solution.add(temp[i]);
}
}
}
return solution;
}
}
Here the subclass
import java.util.Collections;
public class Soave extends EOS {
public Soave (double aFactor, double criticalTemperature, double criticalPressure, double temperature, double pressure, double molecularWeight) {
super(criticalTemperature, criticalPressure, temperature, pressure, molecularWeight);
this.aF = aFactor;
this.fW = 0.48+1.574*aFactor-0.176*Math.pow(aFactor, 2);
}
double aF;
double uValue = 1;
double wValue = 0;
double fW;
public double reducedTemperature = temperature / criticalTemperature;
public double bValue = 0.08664*GAS_CONSTANT*criticalTemperature/criticalPressure;
public double aValue() {
double term1 = 1 - Math.sqrt(reducedTemperature);
double term2 = 1+fW*term1;
double term3 = Math.pow(term2, 2.0);
double term4 = Math.pow(GAS_CONSTANT, 2)*Math.pow(criticalTemperature, 2.0);
return 0.42748*term3*term4/criticalPressure;
}
public double aStarValue = aStar(aValue());
public double bStarValue = bStar(bValue);
public double gasZValue = Collections.max(calculateZ(aStarValue, bStarValue, uValue, wValue));
public double liquidZValue = Collections.min(calculateZ(aStarValue, bStarValue, uValue, wValue));
public double gasDensity = pressure * molecularWeight / (1000 * gasZValue * GAS_CONSTANT * temperature);
public double liquidDensity = pressure * molecularWeight / (1000 * liquidZValue * GAS_CONSTANT * temperature);
}
So now when we create an instance of Soave for the following inputs, we should get for liquidDensity a value of 568.77
double p = 500000;
double t = 318.15;
double pC = 3019900;
double tC = 507.9;
double aF = 0.299;
double mW = 86;
Soave soave = new Soave(aF, tC, pC, t, p, mW);
System.out.println(soave.liquidDensity);

You set your fW variable prior to actually setting the value of aF so it is using the default value of the primitive double which is 0.
Either create a getter for fW where you do the calculations or more the calculation for fW inside the constructor block.
So Either you do like this:
public class Soave extends EOS {
public double aF;
double uValue = 1;
double wValue = 0;
public double fW;
public Soave (double aFactor, double criticalTemperature, double criticalPressure, double temperature, double pressure, double molecularWeight) {
super(criticalTemperature, criticalPressure, temperature, pressure, molecularWeight);
this.aF = aFactor;
fW = 0.48+1.574*aF-0.176*Math.pow(aF, 2); //This will give you the proper number.
}
Alternatively add a getter and do the calculation directly(No need for the fW-variable in the class then).
public double getfWValue() {
return 0.48+1.574*aF-0.176*Math.pow(aF, 2);
}
If so then use that directly in your print-statement instead.
System.out.println(soave.getfWValue());

It is surely the matter of passing the argument or reading it. Look at the piece of code where you pass the value(Most likely you pass 0, it's quite "hard" to make it 0 while reading). If you still can't find your mistake, post the proper code here.

Related

How to solve sine mathematic equation in java?

How to solve following mathematic equation in java?
Equation:
x + sin(x) = constant, where x is variable. I encountered this equation after 18 years. I forgot this basic concept. Please help me on this basic high school question.
I tried to code above equation x + sin(x) = constant as following, however, it is giving wrong answer. Please let me know where i am wrong.
public double balanceLength(double total_weight) {
// 5.00 assume inical value of x
return newtonRaphson( 5.00, total_weight);
}
private static double derivFunc(double x)
{
return sin(x) + x;
}
private static double func(double x, double weight)
{
return sin(x) + x - weight;
}
static double newtonRaphson(double x, double weight)
{
double h = func(x, weight) / derivFunc(x);
while (abs(h) >= EPSILON)
{
h = func(x, weight) / derivFunc(x);
x = x - h;
}
return round(x * 100.0) / 100.0 ;
}
This is a very basic implementation, only partially tested. It reruns x in radians, which satisfies y=six(x) +x for a given y :
//returned value in radians
static double evaluateSinxPlusx(double y){
double delta = y>0 ? 0.01 : -0.01 ;//change constants
double epsilon = 0.01; //to change
int iterations = 100; //accuracy
double x = 0;
double sum = 1;
while(Math.abs(y - sum) > epsilon) {
x+=delta;
//based Taylor series approximation
double term = 1.0;
sum = x;
double d = 1;
for (int i = 1; i< iterations; i++) {
term = Math.pow(x, i);
d*=i;
if (i % 4 == 1) {
sum += term/d;
}
if (i % 4 == 3) {
sum -= term/d;
}
}
}
return x;
}
//test it
public static void main(String[] args) throws Exception{
double y = 0.979;
//expected x = 0.5 radians
System.out.println("for x="+ evaluateSinxPlusx(y)+"(radians), sin(x)+x = "+ y);
y = -0.979;
//expected x = - 0.5 radians
System.out.println("for x="+ evaluateSinxPlusx(y)+"(radians), sin(x)+x = "+ y);
y = 0.33256;
//expected x = 0.16666 radians
System.out.println("for x="+ evaluateSinxPlusx(y)+"(radians), sin(x)+x = "+ y);
}
This is not a robust implementation and should be used as demo only.

Symbol not found, declared array in parameter

This method takes in an array of planets and calculates their net x force component on the planet called upon. I get symbol not found error on compile for a1
public double calcForceExertedByX(Planet[] a1){
double forceX;
for (int i = 0; i < a1.length(); i++){
forceX = forceX + 6.667e-11 *(mass*a1[i].mass)/( xxPos - a1[i].xxPos)*(xxPos - a1[i].xxPos);
}
return forceX;
}
below is the complete code, as requested.
public class Planet {
public double xxPos;
public double yyPos;
public double xxVel;
public double yyVel;
public double mass;
public String imgFileName;
public Planet(double xPs, double yPs, double xVl, double
yVl, double m, String imge){
xxPos = xPs;
yyPos = yPs;
xxVel = xVl;
yyVel = yVl;
mass = m;
imgFileName = imge;
}
public Planet(Planet p){
xxPos = p.xxPos;
yyPos = p.yyPos;
xxVel = p.xxVel;
yyVel = p.yyVel;
mass = p.mass;
imgFileName = p.imgFileName;
}
public double calcDistance(Planet p1){
double distx = xxPos - p1.xxPos;
double disty = yyPos - p1.yyPos;
double dist = Math.sqrt(distx*distx + disty*disty);
return dist;
}
public double calcForceExertedBy(Planet p1){
double force = 6.667e-11 *(mass*p1.mass)/(this.calcDistance(p1)*this.calcDistance(p1));
return force;
}
public double calcForceExertedByX(Planet[] a1){
double forceX;
for (int i = 0; i < a1.length(); i++){
forceX = forceX + 6.667e-11 *(mass*a1[i].mass)/( xxPos - a1[i].xxPos)*(xxPos - a1[i].xxPos);
}
return forceX;
}
public double calcForceExertedByY(Planet[] a1){
double forceY;
for (int i = 0; i <a1.length(); i++){
forceY = forceY + 6.667e-11 *(mass*a1[i].mass)/( yyPos - a1[i].yyPos)*(yyPos - a1[i].yyPos);
}
return forceY;
}
}
Windows 7 JAVAc 11.01
I am guessing the error that is trying to be referenced is that Planet[] a1 does not have method length(). Arrays use .length rather than a method call.
Also forceX is not initialised.

Can't perform actions with objects

I am an engineering student, busy with a project using DrJava as an IDE (it is the standard IDE we use during the course), and the Princeton STDLIB.
I have been having problems with understanding, writing and using objects. I would like to ask what is wrong with the way I wrote my following code. I will give the error lines after the coding:
public class GameObject
{
// Default implementation of a game object
private double G = 6.67408e-11;
private double radiusKoeff = 0.01;
public class Planet
{
double mass;
double size;
double velocityX;
double velocityY;
double positionX;
double positionY;
public Planet(double m, double vx, double vy, double px, double py)
{
mass = m;
size = m * radiusKoeff;
velocityX = vx;
velocityY = vy;
positionX = px;
positionY = py;
}//constructor for the planet type
public double GravForce(Planet a, Planet b)
{
double distanceX, distanceY, distance;
distanceX = Math.abs(a.positionX - b.positionX);
distanceY = Math.abs(a.positionY - b.positionY);
distance = Math.sqrt((distanceX)*(distanceX) + (distanceY)*(distanceY));
double force = (G * a.mass * b.mass) / (distance*distance);
return force;
}//calculates the gravitational force between two objects
}
public static void main(String[] args)
{
String filename = args[0];
Planet first = new Planet(1.25e24, 1, 0, 0, 0);
Planet second = new Planet(1e24, 1, 0, 5, 0);
**StdOut.println(GravForce( first, second ));**
}
}
Error: The method GravForce(GameObject.Planet, GameObject.Planet) is undefined for the type GameObject.
The error is thrown for the GravForce function I try to call.
Any help would be greatly appreciated.
Modify your method like this
public double GravForce(Planet b)
{
double distanceX, distanceY, distance;
distanceX = Math.abs(this.positionX - b.positionX);
distanceY = Math.abs(this.positionY - b.positionY);
distance = Math.sqrt((distanceX)*(distanceX) + (distanceY)*(distanceY));
double force = (G * this.mass * b.mass) / (distance*distance);
return force;
}//calculates the gravitational force between two objects
Then in main
public static void main(String[] args)
{
String filename = args[0];
Planet first = new Planet(1.25e24, 1, 0, 0, 0);
Planet second = new Planet(1e24, 1, 0, 5, 0);
StdOut.println(first.GravForce(second));
}

No convergence with batch gradient descent

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!

Color - Finding the closest color

I was following the guidelines as described here, but when my android app examines a picture taken in a well-lit room and tries to match every color to the closest basic color (black, red, blue, green, etc.), most of the colors are associated with black. I have no idea why this happens and I have spent 3 hours examining my code to find out where the flaw was. Can anyone suggest where my error is?
Here is my code:
public double getMinEValue(int color1, int color2) {
double result_value = 0;
double[] color1_values = getColorValues(color1);
double[] color2_values = getColorValues(color2);
double delta_L = color1_values[0] - color2_values[0];
double delta_C = Math.sqrt(Math.pow(color1_values[1], 2)+Math.pow(color1_values[2], 2))-Math.sqrt(Math.pow(color2_values[1], 2)+Math.pow(color2_values[2], 2));
double delta_a = color1_values[1]-color2_values[1];
double delta_b = color1_values[2]-color2_values[2];
double delta_H = Math.sqrt(Math.pow(delta_a, 2)+Math.pow(delta_b, 2)+Math.pow(delta_C, 2));
double k_1 = 0.045; double k_2 = 0.015;
double s_c = 1+k_1*Math.sqrt(Math.pow(color1_values[1], 2)+Math.pow(color1_values[2], 2));
double s_h = 1+k_2*Math.sqrt(Math.pow(color1_values[1], 2)+Math.pow(color1_values[2], 2));
result_value = Math.sqrt(Math.pow(delta_L, 2)+Math.pow((delta_C/s_c), 2)+Math.pow((delta_H/s_h), 2));
return result_value;
}
public double[] getColorValues(int color1) {
double[] return_value = new double[3];
double r = Color.red(color1)/255;
double g = Color.green(color1)/255;
double b = Color.blue(color1)/255;
double r_linear = makeLinear(r) * 100;
double g_linear = makeLinear(g) * 100;
double b_linear = makeLinear(b) * 100;
double[][] matrix = {{0.4124, 0.3576, 0.1805}, {0.2126, 0.7152, 0.0722}, {0.0193, 0.1192, 0.9508}};
double[] linear_matrix = {r_linear, g_linear, b_linear};
double[] result_matrix = new double[3];
result_matrix = multiplyMatrices(matrix, linear_matrix);
//double X_n = 109.85; double Y_n = 100.00; double Z_n = 35.58; // Illuminant A
double X_n = 95.047; double Y_n = 100.00; double Z_n = 108.883; // D65
double L_star = 116*f(result_matrix[1]/Y_n)-16;
double a_star = 500*(f(result_matrix[0]/X_n)-f(result_matrix[1]/Y_n));
double b_star = 200*(f(result_matrix[1]/Y_n)-f(result_matrix[2]/Z_n));
return_value[0] = L_star; return_value[1] = a_star; return_value[2] = b_star;
return return_value;
}
private double f(double t) {
double return_value;
if (Double.compare(t, Math.pow((6/29), 3)) > 0) {
return_value = Math.pow(t, (1/3));
} else {
return_value = (1/3)*Math.pow((29/6), 2)*t+(4/29);
}
return return_value;
}
private double makeLinear(double c) {
double return_value = 0;
if (Double.compare(0.04045, c)<=0) {
return_value = c/12.92;
} else {
double a = 0.055;
return_value = Math.pow(((c + a) / (1 + a)), 2.4);
}
return return_value;
}
private double[] multiplyMatrices(double[][] matrix, double[] other_matrix) {
double[] return_matrix = new double[3];
for (int i=0; i<3; i++) {
for (int j=0; j<3; j++) {
return_matrix[i] += matrix[i][j]*other_matrix[j];
}
}
return return_matrix;
}
You've got a whole lot of integer divisions that need to be floating point divisions. You need to cast one of the operands of each division to double, or include a decimal point, to get these to work. For example, you have
Color.red(color1)/255
which should be
Color.red(color1)/255.0
and you also have expressions like
(1/3)*Math.pow((29/6), 2)*t+(4/29);
which needs to be
(1.0/3)*Math.pow((29.0/6), 2)*t+(4.0/29);
and many others. You have made this same mistake several times.

Categories

Resources