Newton-Raphson method using the Math.Commons library - java

I made a test program to try the NewtonRaphsonSolver class through the Apache Commons Math library. Newton's method is used to find roots for a given function.
The test program that I wrote references the cos(x) function (I have a more difficult function to analyze and am looking at the cos(x) function first).
The code for the test program is
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;
import org.apache.commons.math3.analysis.solvers.*;
import org.apache.commons.math3.exception.DimensionMismatchException;
public class Test3 {
public static void main(String args[]) {
NewtonRaphsonSolver test = new NewtonRaphsonSolver();
UnivariateDifferentiableFunction f = new UnivariateDifferentiableFunction() {
public double value(double x) {
return Math.cos(x);
}
#Override
public DerivativeStructure value(DerivativeStructure t) throws DimensionMismatchException {
return t.cos();
}
};
for (int i = 1; i <= 500; i++) {
System.out.println(test.solve(1000, f, i, i+0.1));
}
}
}
Not certain if I needed to reference Math.cos(x) and t.cos() twice
public double value(double x) {
return Math.cos(x);
}
#Override
public DerivativeStructure value(DerivativeStructure t) throws DimensionMismatchException {
return t.cos();
}
Newton's method finds all of the zeroes and displays them to the user.
1.5707963267948966
1.5707963267948966
-7.853981633974483
4.71238898038469
4.71238898038469
1.5707963267948966
7.853981633974483
7.853981633974483
10.995574287564276
10.995574287564276
10.995574287564276
10.995574287564276
14.137166941154069
14.137166941154069
14.137166941154069
127.23450247038663
17.278759594743864
17.278759594743864
23.56194490192345
20.420352248333657
20.420352248333657
39.269908169872416
23.56194490192345
23.56194490192345
14.137166941154069
26.703537555513243
26.703537555513243
23.56194490192345
29.845130209103036
29.845130209103036
26.703537555513243
32.98672286269283
32.98672286269283
32.98672286269283
36.12831551628262
36.12831551628262
36.12831551628262
23.56194490192345
39.269908169872416
39.269908169872416
45.553093477052
42.411500823462205
42.411500823462205
Is there some way to prevent printing out zeroes that are duplicates? For example, the above output would read
1.5707963267948966
4.71238898038469
7.853981633974483
10.995574287564276
14.137166941154069
17.278759594743864
20.420352248333657
23.56194490192345
26.703537555513243
29.845130209103036
32.98672286269283
36.12831551628262
39.269908169872416
42.411500823462205
45.553093477052
Can this be done inside a for loop or through an array which only prints out values which are not duplicates?

First question is , what are the same zeros. I would make a class:
class SolutionForZero{
public final double value;
final int hash;
static double tolerance = 1e-6;
public SolutionForZero(double value){
this.value = value;
hash = 1;
}
public boolean equals(Object other){
if( other instanceof SolutionForZero ){
double v = value - other.value;
return (v < 0) ? (-v > tolerance) : (v > tolerance);
}
return false;
}
public int hashCode(){
return hash;
}
}
This class will compare the doubles. To use this class:
Set<SolutionForZero> resultSet = new HashSet<>();
for(double d: yourAnswers){
if(resultSet.add(new SolutionForZero(d))){
System.out.println("'unique' zero at: " + d);
};
}
Now your resultSet will contain only values that are at least tolerance apart.
The hashcode is a bit tricky. The way I have provided will work as long as tolerance is smaller than 1.0. I would appreciate improvements.

import java.util.TreeSet;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;
import org.apache.commons.math3.analysis.solvers.*;
import org.apache.commons.math3.exception.DimensionMismatchException;
public class Test5 {
public static void main(String args[]) {
NewtonRaphsonSolver test = new NewtonRaphsonSolver(1E-10);
UnivariateDifferentiableFunction f = new UnivariateDifferentiableFunction() {
public double value(double x) {
return Math.sin(x);
}
public DerivativeStructure value(DerivativeStructure t) throws
DimensionMismatchException {
return t.sin();
}
};
double EPSILON = 1e-6;
TreeSet<Double> set = new TreeSet<>();
for (int i = 1; i <= 5000; i++) {
set.add(test.solve(1000, f, i, i + EPSILON));
}
for (Double s : set) {
if (s > 0) {
System.out.println(s);
}
}
}
}

Related

How to check in jUnit the equality of objects with double fields

We all know how to correctly check for fractional numbers in tests (using TOLERANCE):
class OxygenTankTest {
static final double TOLERANCE = 0.001;
#Test
void testFilling() {
OxygenTank tank = OxygenTank.withCapacity(100);
tank.fill(5.8);
tank.fill(5.6);
Assertions.assertEquals(0.114, tank.getStatus(), TOLERANCE);
}
}
But my question is how to check if we need to check not the individual values - but whole objects.
For example:
Need to test Summer - which performs the summation of fields
public class Summer {
public void setSum(Item itemTo, Item itemFrom) {
itemTo.setDiameter(itemTo.getDiameter() + itemFrom.getDiameter());
itemTo.setLength(itemTo.getLength() + itemFrom.getLength());
}
}
public class Item {
private Double diameter;
private Double length;
public Item(Double diameter, Double length) {
this.diameter = diameter;
this.length = length;
}
public Double getDiameter() {
return diameter;
}
public void setDiameter(Double diameter) {
this.diameter = diameter;
}
public Double getLength() {
return length;
}
public void setLength(Double length) {
this.length = length;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Item item = (Item) o;
if (diameter != null ? !diameter.equals(item.diameter) : item.diameter != null) return false;
return length != null ? length.equals(item.length) : item.length == null;
}
#Override
public int hashCode() {
int result = diameter != null ? diameter.hashCode() : 0;
result = 31 * result + (length != null ? length.hashCode() : 0);
return result;
}
#Override
public String toString() {
final StringBuffer sb = new StringBuffer("Item{");
sb.append("diameter=").append(diameter);
sb.append(", length=").append(length);
sb.append('}');
return sb.toString();
}
}
How i try to write a test:
public class SummerTest {
#Test
public void setSum() {
Summer summer = new Summer();
Item itemFrom = new Item(2.321, 1.111);
Item itemTo = new Item(0.999, 0.999);
summer.setSum(itemFrom, itemTo);
// expected
Item expectedItem = new Item(3.32, 2.11);
assertThat(itemFrom, equalTo(expectedItem));
}
}
But it does not work!
java.lang.AssertionError:
Expected: <Item{diameter=3.32, length=2.11}>
but: was <Item{diameter=3.3200000000000003, length=2.11}>
Expected :<Item{diameter=3.32, length=2.11}>
Actual :<Item{diameter=3.3200000000000003, length=2.11}>
<Click to see difference>
How to properly check for compliance?
You overwrote the equals method that checks for exact equality. If you have objects that contain floating point values (float, double) that are considered in your equals implementation, you will want to not compare the object itself, but the values within the object:
assertEquals(expected.getDiameter(), itemFrom.getDiameter(), TOLERANCE);
assertEquals(expected.getLength(), itemFrom.getLength(), TOLERANCE);
Or if you want to get fancy you can create your own Matcher that goes into the assertThat.
Consider changing the set up of the test to allow for exact comparisons via Item::equals:
private static final double ITEM_FROM_DIAMETER = 2.321;
private static final double ITEM_FROM_LENGTH = 1.111;
private static final double ITEM_TO_DIAMETER = 0.999;
private static final double ITEM_TO_LENGTH = 0.999;
Item itemFrom = new Item(ITEM_FROM_DIAMETER, ITEM_FROM_LENGTH);
Item itemTo = new Item(ITEM_TO_DIAMETER, ITEM_TO_LENGTH);
Item expectedItem = new Item(ITEM_FROM_DIAMETER + ITEM_TO_DIAMETER, ITEM_FROM_LENGTH + ITEM_TO_LENGTH);
Also, since Item is mutable, it would be a good idea to assert itemFrom was not changed.

Getting 'Infinity' output instead of actual numbers

I am practicing some Java and one of the applications I am writing asks to output the world population in the next 75 years.
I am using the population growth model. My issue is that my application outputs 'Infinity' in the column where the estimated population should be output.
This is my code:
import java.util.Calendar;
import java.util.regex.Matcher;
public class WorldPopulationGrowth {
public static void main(String[] args) {
double currentWorldPopulation = 7.4e9;
double worldPopulationGrowthRate = 1.13;
double anticipatedWorldPopulation;
int initialYear = Calendar.getInstance().get(Calendar.YEAR);
System.out.println("Year\tAnticipated World Population (in billions)\tPopulation " +
"increase since last year");
System.out.println(String.format("%d\t%.1e\t\t\t\t\t\t\t\t\t\t\tNA", initialYear, currentWorldPopulation) );
for(int i=1; i < 76; i++){
int year = initialYear + i;
double growthExponential = worldPopulationGrowthRate*year*1.0;
anticipatedWorldPopulation = currentWorldPopulation * Math.pow(Math.E, growthExponential);
System.out.println(String.format("%d\t%.1e\t\t\t\t\t\t\t\t\t\t\t", year, anticipatedWorldPopulation));
currentWorldPopulation = anticipatedWorldPopulation;
}
}
}
Let's take a careful look at the first iteration of your code, as if we were debugging it (Make sure you try to do this in the future!)
currentWorldPopulation = 7.4e9
worldPopulationGrowthRate is 1.13
initialYear is 2016
your loop begins, i is 1
year is set to 2017
growthExponential is set to 1.13 * 2017 = 2279.21 (this is the start of your problem)
anticipatedWorldPopulation is set to 7.4e9 * e^2279.21
this is roughly 7.4e9 * 7.05e989... KABOOM
Revisit your calculations, and step through your application (ideally in a debugger) to see your problems.
#Krease found your problem.
I recoded it. Once you fix the issue he found it's fine. I used JDK 8 lambdas and gave you both percentage and exponential growth models. The code prints both for comparison:
import java.util.function.DoubleFunction;
/**
* Simplistic population growth model
* #link https://stackoverflow.com/questions/38805318/getting-infinity-output-instead-of-actual-numbers/38805409?noredirect=1#comment64979614_38805409
*/
public class WorldPopulationGrowth {
public static void main(String[] args) {
double currentWorldPopulation = 7.4e9;
double worldPopulationGrowthRate = 1.13;
int numYears = 76;
int startYear = 1976;
double populationExponential = currentWorldPopulation;
ExponentialGrowthModel modelExpGrowth = new ExponentialGrowthModel(worldPopulationGrowthRate);
double populationPercentage = currentWorldPopulation;
PercentageGrowthModel modelPercentGrowth = new PercentageGrowthModel(worldPopulationGrowthRate);
System.out.println(String.format("%10s %20.3e %20.3e", startYear, currentWorldPopulation, currentWorldPopulation));
for (int i = 1; i < numYears; ++i) {
populationExponential = modelExpGrowth.apply(populationExponential);
populationPercentage = modelPercentGrowth.apply(populationPercentage);
System.out.println(String.format("%10s %20.3e %20.3e", startYear+i, populationExponential, populationPercentage));
}
}
}
class ExponentialGrowthModel implements DoubleFunction<Double> {
private double exponent;
ExponentialGrowthModel(double exponent) {
this.exponent = exponent;
}
private double getExponent() {
return exponent;
}
public void setExponent(double exponent) {
this.exponent = exponent;
}
#Override
public Double apply(double value) {
return value*Math.exp(this.getExponent());
}
}
class PercentageGrowthModel implements DoubleFunction<Double> {
private double percentageIncrease;
PercentageGrowthModel(double percentageIncrease) {
this.percentageIncrease = percentageIncrease;
}
private double getPercentageIncrease() {
return percentageIncrease;
}
public void setPercentageIncrease(double percentageIncrease) {
this.percentageIncrease = percentageIncrease;
}
#Override
public Double apply(double value) {
return value*(this.getPercentageIncrease());
}
}

Why won't my method print out?

I've made a main method in one class and a lot of other small methods in another class. When I call on them in my main method using their location and making sure that they would outprint if I called on them, they still don't outprint. Only the print two methods show any output. I'm not sure how to go about fixing it so I haven't tried many things yet. Could you look at my code and check why they aren't working?
Update: I've managed to get all the line in the main method except for 28 working with the help I received. Now all that's left is that one output. I've changed the code so it works a bit better and will shut down if it doesn't output, but the output is still missing.package rational;
My Main Method
package rational;
/**
*
* #author Dominique
*/
public class Rational {
public static String number() {
rational1 number= new rational1(27, 3);
String r3= number.printRational(number);
return r3;
}
public static void main(String[] args) {
rational1 number= new rational1(27,3);
System.out.println(number());
String r3=number();
System.out.println(rational1.toDouble(27,3 ));
rational1.add(number);
rational1.invert(r3, number);
rational1.negate(r3, number);
rational1.toDouble(27, 3);
}
}
My Other Method Class
package rational;
/**
*
* #author Dominique
*/
public class rational1 {
public int top;
public int bottom;
public rational1 () {
this.top = 0;
this.bottom = 0;
}
public rational1(int top, int bottom){
this.top=top;
this.bottom=bottom;
}
public String printRational(rational1 r1){
String r3=("Your fraction is "+String.format(r1.top+" / "+r1.bottom));
return r3;
}
public static void invert(String r2, rational1 r1) {
int index = r2.indexOf('s');
if (index != -1) {
System.out.print(r2.substring(0, index+1));//works
System.out.println(" "+r1.bottom + "/" + r1.top);
index++;
}
else {
System.exit(0);
}
}
public static void negate(String r2, rational1 r1){
int index = r2.indexOf('-');
if (index != -1) {
String stringValueOf = String.valueOf(r1.top);
System.out.println(r2.substring(0, 17));//works
System.out.println(r1.bottom+"/"+stringValueOf.substring(1));
index++;
}
}
public static double toDouble(int one, int two){
int three= one/two;
return three;
}
public static double gcd( double a, double b)
{
double r = a % b;
if (r != 0)
{
return gcd(b, r );
}
else
{
return b;
}
}
public static double reduce(double t, double b){
double numberone=gcd(t, b);
double pick=numberone*(b/t);
return pick;
}
public static double add(rational1 r1){
double pickone=(r1.top);
double choice= pickone+pickone;
double choice2=reduce(choice, r1.bottom);
return choice2;
}
}
So the problem is in invert method:
public static void invert(String r2, rational1 r1){
int index = 0;
while (index < 1) {
if (r2.charAt(index) == '/') {
System.out.print(r2.substring(0, 17));
System.out.print(r1.bottom+"/"+r1.top);
index++;
}else{
System.exit(0);
}
`}
}
This method immediate checks the character at r2.charAt(index) == '/'), but this is never the case. Because the character at index = 0 is 'Y' from the printRational method. Because that's not the case then System.exit(0) gets called which immediately ends the program without running the rest of the program.
I believe that this code will work.
public static void invert(String r2, rational1 r1) {
int index = r2.indexOf('/');
if (index != -1) {
index++;
}
else {
System.out.print(r2.substring(0, index));//works
System.out.print(r1.bottom + "/" + r1.top);
}
}
The print method does not necessarily flush the buffer to the screen. Try replacing the print method with the println method.
Once this is in rational package., try to change the system.out.print to system.out.println .Basically all your codes are okay. Try look at this link.
Click [here] (http://introcs.cs.princeton.edu/java/92symbolic/Rational.java.html)!

Sum of Multiples of 3 and 5 using Methods: Incorrect sum coming

I have been trying to solve Project Euler Problem #1 using "methods" in Java. It is giving correct multiples. However, sum is not coming right. Here are my codes:
Method Class:
package lessons;
public class method {
int a,b, add;
public void multipleThree()
{
for (a=3; a<1000; a+=3)
{
System.out.println(a);
}
}
public void multipleFive(){
for (b=5; b<1000; b+=5)
{
System.out.println(b);
}
}
public void sum(){
add= a+b;
System.out.println("The sum is "+ add);
}
}
Main Class
package lessons;
public class Lessons {
public static void main(String[] args) {
method problem = new method();
problem.multipleThree();
problem.multipleFive();
problem.sum();
}}
Any helps???
a+b is calculated once - outside your loop. The result will be the sum of the final values of a and b. If you want to sum each element in each loop, you'll need to update add inside the loops:
public class method {
int add = 0;
public void multipleThree() {
for (int a=3; a<1000; a+=3) {
System.out.println(a);
add += a;
}
}
public void multipleFive(){
for (int b=5; b<1000; b+=5) {
System.out.println(b);
add += b;
}
}
public void sum(){
System.out.println("The sum is "+ add);
}
}
The output for multipleThree() and multipleFive() is 999 and 995 accordingly. However a and b are incremented in the for loops one more time to meet the exit condition therefor their sum is 2002 and not 1994.
You can change sum() to this
public void sum(){
add = a + b - 8;
System.out.println("The sum is "+ add);
}
Declare variables separately,
class method {
int i, j, add;
public void multipleThree() {
for (int a = 3; a < 1000; a = a + 3) {
System.out.println(a);
i = a;
}
}
public void multipleFive() {
for (int b = 5; b < 1000; b = b + 5) {
System.out.println(b);
j = b;
}
}
public void sum() {
add = i + j;
System.out.println("The sum is " + add);
}
}
Check below
package lessons;
public class method {
int a,b, add;
public void multipleThree()
{
for (a=3; a<1000; a+=3)
{
System.out.println(a);
}
a=a-3;//added this
}
public void multipleFive(){
for (b=5; b<1000; b+=5)
{
System.out.println(b);
}
b=b-5;//added this
}
public void sum(){
add= a+b;
System.out.println("The sum is "+ add);
}
}
import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
public class Solution {
public static void main(String[] args) {
Scanner z = new Scanner(System.in);
int N = z.nextInt();
while(N!=0)
{
long number = z.nextInt();
long p = (number-1)/3;
long sum1 = (p*(6+((p-1)*3)))/2;
long q = (number-1)/5;
long sum2 = (q*(10+((q-1)*5)))/2;
long r = (number-1)/15;
long sum3 = (r*(30+((r-1)*15)))/2;
System.out.println(sum1+sum2-sum3);
}
}
}
This is best way to solve the given problem passed all test cases.Happy coding

Check repetition of fractions of external file

I'm creating a program that has a requirement of three classes. The program reads an external text file filled with fractions, and is to return how many times each fraction is repeated. 4/2 has to be reduced to 2/1 and is +1 for the 2/1 count. I believe I am almost done, but I cannot figure out what I need to put into my compareAndIncrement() method in my FractionCounter class. It is suppose to be used to see if the newFraction passed into the function is the same as the Fraction being stored, and if so increments the counter by one and returns true (otherwise, returns false). Below are the codes for my classes.
FractionCounter
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.Scanner;
public class FractionCounter {
private Fraction theFraction;
private int counter = 0;
public FractionCounter(Fraction theFraction ){
}
public boolean compareAndIncrement(Fraction newFraction){
return false;
}
public String toString(){
return "";
}
public static void main(String[] args){
ObjectList num = new ObjectList();
ObjectList den = new ObjectList();
Scanner fractionFile = null;
try{
fractionFile = new Scanner(new FileInputStream("fractions.txt"));
}
catch (FileNotFoundException e){
System.out.println("File not found.");
System.exit(0);
}
while (fractionFile.hasNextLine()){
String[] part = (fractionFile.nextLine().split("/"));
num.add(Integer.parseInt(part[0]));
den.add(Integer.parseInt(part[1]));
}
}
}
Fraction
public class Fraction {
private int numerator;
private int denominator;
public Fraction() {
}
public Fraction(int num, int den) {
setNumerator(num);
setDenominator(den);
}
public void setNumerator(int num) { //sets numerator
numerator = num;
}
public int getNumerator() { //gets numerator
return numerator;
}
public void setDenominator(int den) { //sets denominator
if(den == 0) {
System.out.println("Error: Denominator = 0");
System.exit(0);
} else {
denominator = den;
}
}
public int getDenominator() { //gets denominator
return denominator;
}
public boolean equals(Fraction that) {
return ((double)this.numerator/this.denominator) == ((double)that.numerator/that.denominator);
}
}
ObjectList
public class ObjectList {
private int[] fraction = new int[100];
private int numElements = 0;
public void add(int n){
fraction[numElements] = n;
numElements++;
}
public String toString(){
String retVal = "";
for (int i = 0; i < numElements; i++){
retVal += fraction[i] + ",";
}
return retVal;
}
public int indexOf(int[] input, int target) {
//returns the index of the inputed value
if(contains(input,target) == true){
for(int i = 0;i <= target;i++) {
if(input[i] == target) {
return i;
}
}
}
return -1;
}
public boolean contains(int[] input, int target) {
//is the target in the inputed array?
for(int i=0;i<input.length; i++) {
if(input[i] == target) {
return true;
}
}
return false;
}
}
Any hints or tips for what I need to do to my method would be much appreciated. I can't figure out a way to do it without using numElements and fraction variables from my ObjectList class. Thank you
I would make a Map to make the counter :
private static final Map<Fraction, Integer> counter = new HashMap<Fraction, Integer>();
and for each Fraction element read for the file I would do :
if(counter.containsKey(fraction)){
Integer count = counter.get(fraction);
count++;
counter.put(fraction, count);
} else {
counter.put(fraction, 1);
}
Moreover, I would make a static parse fonction in the Fraction class which return a Fraction instance from the line you just read. And a toString function to print it easely.

Categories