Hi guys I´m new in java.
I'm trying to convert an octave function in to Java(using JBlas) but I´m not sure how to do this line:
OCTAVE: Thetas{i} = rand(sizes(i+1), sizes(i) + 1)*2*EPSILON-EPSILON;
My code in Java:
public class InitializeThetas {
public static DoubleMatrix InitializeThetas(DoubleMatrix sizes, double epsilon)
{
int L= sizes.length;
epsilon = 0.03;
DoubleMatrix Thetas = new DoubleMatrix(new double[]{});
Random r = new Random();
for (int i = 1; i <= L - 1; i++)
{
//Thetas{i} = rand(sizes(i+1), sizes(i) + 1)*2*EPSILON-EPSILON;
Thetas.data[i]= r.nextInt() * 2 * epsilon - epsilon;
}
return Thetas;
}
}
Is this close to what you want?
public class InitializeThetas {
public static Collection<DoubleMatrix> InitializeThetas(DoubleMatrix sizes, double epsilon)
{
int L= sizes.length;
epsilon = 0.03;
Collection<DoubleMatrix> Thetas = new ArrayList<DoubleMatrix>();
for (int i = 0; i < L - 1; i++)
{
Thetas.add(DoubleMatrix.rand(Double.valueOf(sizes.get(i + 1)).intValue(), Double.valueOf(sizes.get(i)).intValue() + 1).mul(2).mul(epsilon).sub(epsilon));
}
return Thetas;
}
public static void main(String[] args) {
DoubleMatrix soze = new DoubleMatrix(10);
for(int i = 0;i<10;i++){
soze.put(i,i+1);
}
System.out.println(InitializeThetas(soze,1.1));
}
}
Related
I am currently trying to program a neural network... for learning I want to use the backpropagation algorithm! My problem is, that I don't know where my error is.
I try to train it the logical AND.
My network errors after the first round are:
28.68880035284087 for INPUT 1|1
22.17048518538824 for INPUT 1|0
21.346787829014342 for INPUT 0|1
20.44791655274438 for INPUT 0|0
If I make a few iterations my errors are like this:
34.17584528001372 for INPUT 1|1
18.315643070675343 for INPUT 1|0
17.568891920535222 for INPUT 0|1
17.753497551261436 for INPUT 0|0
I have absolutely no idea why the error for INPUT 1|1 is growing, while the others get smaller...
Here's my code:
classes for the testdata:
public class Trainingset
{
private double[] input;
private double[] target;
public Trainingset(double[] input, double[] target)
{
this.input = input;
this.target = target;
}
public double[] getInput()
{
return input;
}
public double[] getTarget()
{
return target;
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
public class TrainingData
{
private List<Trainingset> trainingSets;
private Random random;
private int nextEntry;
public TrainingData()
{
random = new Random();
trainingSets = new ArrayList<Trainingset>();
nextEntry = 0;
}
public void addData(double[] input, double[] target)
{
Trainingset ts = new Trainingset(input.clone(), target.clone());
trainingSets.add(ts);
}
public Trainingset getRandomTrainingset()
{
return trainingSets.get(random.nextInt(trainingSets.size()));
}
public Trainingset getNext()
{
if(nextEntry == trainingSets.size())
nextEntry = 0;
return trainingSets.get(nextEntry++);
}
}
the networkclass:
import java.util.ArrayList;
import java.util.List;
public class FFN3
{
private List<FFNlayer3> layers;
private double learningrate = 0.45;
private double momentum = 0.9;
private double outputError;
private double networkErrkor;
public FFN3()
{
layers = new ArrayList<>();
layers.add(new FFNlayer3(2));
layers.add(new FFNlayer3(1));
layers.get(0).setNextLayer(layers.get(1));
layers.get(1).setPrevLayer(layers.get(0));
double[][] ItoH = {
{ 0.4, 0.1 },
{ -0.1, -0.1 }
};
double[][] HtoO = {
{ 0.06, -0.4 }
};
layers.get(0).setWeights(ItoH);
layers.get(1).setWeights(HtoO);
networkErrkor = Double.MAX_VALUE;
}
public void learn(TrainingData td)
{
Trainingset ts = td.getNext();
double[] results = compute(ts.getInput());
double error = 0;
for(int i = 0; i < results.length; i++)
{
error += Math.pow(ts.getTarget()[i] - results[i], 2);
}
networkErrkor = error / results.length;
layers.get(layers.size()-1).updateWeights(learningrate, momentum, ts.getTarget());
layers.get(0).updateHiddenWeights(learningrate, momentum, ts.getInput());
}
public double getNetworkError()
{
return networkErrkor;
}
public double[] compute(double[] input)
{
return layers.get(0).compute(input);
}
}
The layerclass:
public class FFNlayer3
{
private double[][] incomingWeights;
private double[][] prevWeightChanges;
private double[] neuronValues;
private double[] neuronSums;
private double[] errors;
private FFNlayer3 prevLayer;
private FFNlayer3 nextLayer;
public FFNlayer3(int neuroncount)
{
neuronValues = new double[neuroncount];
neuronSums = new double[neuroncount];
errors = new double[neuroncount];
nextLayer = null;
prevLayer = null;
}
public void setWeights(double[][] weights)
{
incomingWeights = weights;
prevWeightChanges = new double[incomingWeights.length][incomingWeights[0].length];
}
public void setPrevLayer(FFNlayer3 prevLayer)
{
this.prevLayer = prevLayer;
}
public void setNextLayer(FFNlayer3 nextLayer)
{
this.nextLayer = nextLayer;
}
public void updateWeights(double learningrate, double momentum, double[] targetValues)
{
for(int i = 0; i < errors.length; i++)
{
errors[i] = neuronValues[i] * (1 - neuronValues[i]) * (targetValues[i] - neuronValues[i]);
}
for(int i = 0; i < incomingWeights.length; i++)
{
for(int j = 0; j < incomingWeights[i].length; j++)
{
double delta = learningrate * errors[i] * prevLayer.getNeuronValues()[j];
incomingWeights[i][j] += delta + momentum * prevWeightChanges[i][j];
}
}
prevLayer.updateHiddenWeights(learningrate, momentum);
}
public void updateHiddenWeights(double learningrate, double momentum)
{
if(prevLayer==null)
return;
for(int i = 0; i < errors.length; i++)
{
for(int j = 0; j < nextLayer.getErrors().length; j++)
{
errors[i] += nextLayer.getErrors()[j] * nextLayer.getWeights()[j][i];
}
}
for(int i = 0; i < incomingWeights.length; i++)
{
for(int j = 0; j < incomingWeights[i].length; j++)
{
double delta = learningrate * errors[i] * prevLayer.getNeuronValues()[j];
incomingWeights[i][j] += delta + momentum * prevWeightChanges[i][j];
}
}
prevLayer.updateHiddenWeights(learningrate, momentum);
}
public void updateHiddenWeights(double learningrate, double momentum, double[] input)
{
for(int i = 0; i < errors.length; i++)
{
for(int j = 0; j < nextLayer.getErrors().length; j++)
{
errors[i] += nextLayer.getErrors()[j] * nextLayer.getWeights()[j][i];
}
}
for(int i = 0; i < incomingWeights.length; i++)
{
for(int j = 0; j < incomingWeights[i].length; j++)
{
double delta = learningrate * errors[i] * input[j];
incomingWeights[i][j] += delta + momentum * prevWeightChanges[i][j];
}
}
}
public double[][] getWeights()
{
return incomingWeights;
}
public double[] getErrors()
{
return errors;
}
public double[] getNeuronValues()
{
return neuronValues;
}
public double[] compute(double[] input)
{
for(int i = 0; i < neuronValues.length; i++)
{
for(int j = 0; j < incomingWeights[i].length; j++)
{
neuronSums[i] += input[j] * incomingWeights[i][j];
}
neuronValues[i] = SIGMOID(neuronSums[i]);
neuronSums = new double[neuronSums.length];
}
if(nextLayer==null)
return neuronValues;
return nextLayer.compute(neuronValues);
}
private double SIGMOID(double value)
{
return 1 / (1+ Math.exp(-value));
}
}
And the snippet from my main:
FFN3 network = new FFN3();
double[] input = new double[2];
double[] target = new double[1];
TrainingData td = new TrainingData();
input[0] = 1;
input[1] = 1;
target[0] = 1;
td.addData(input, target);
input[0] = 1;
input[1] = 0;
target[0] = 0;
//target[1] = 1;
td.addData(input, target);
input[0] = 0;
input[1] = 1;
target[0] = 0;
td.addData(input, target);
input[0] = 0;
input[1] = 0;
target[0] = 0;
td.addData(input, target);
while(Double.compare(network.getNetworkError(), 0.001)>0)
{
network.learn(td);
System.out.println(network.getNetworkError()*100);
}
I was using this document: http://www.dataminingmasters.com/uploads/studentProjects/NeuralNetworks.pdf
The values after the first epoch are similar to the values in the document... what is wrong? Is it the document, my code or both?
Hope you can help me!
you may try with BigDecimal instead of double, as they could cause trouble (look here for further information )
I need to fill a 2D Array with numbers between 2 and 6, given by the user (is just part of a bigger proyect) but when I give the number I only get another request for a number.
public static int[][] crearTablero(int tamaño)
{
int[][] tablero = new int[tamaño][tamaño];
return tablero;
}
public static void imprimeTablero(int[][] tablero)
{
for(int i = 0; i<tablero.length; i++)
{
for(int j = 0; j<tablero[i].length; j++)
{
System.out.print(tablero[i][j] + " ");
}
System.out.println();
}
}
public static void swap(int[][] tablero, int x1, int y1, int x2, int y2)
{
int temp = tablero[x1][y1];
tablero[x1][y1] = tablero[x2][y2];
tablero[x2][y2] = temp;
}
public static void rellenarTablero(int[][] tablero) {
for (int x = 0; x < tablero.length; x++) {
for (int y = 0; y < tablero[x].length; y++) {
tablero[x][y] = aleatorio(numeroColores());
}
}
}
public static void shuffleBoard(int[][] tablero)
{
Random rnd = new Random();
int randX = 0;
for(int x = 0; x<tablero.length; x++)
{
randX = rnd.nextInt(tablero.length);
int[] temp = tablero[x];
tablero[x] = tablero[randX];
tablero[randX] = temp;
}
}
public static int numeroColores(){
int colores = 0;
System.out.print("Numero de colores (entre 2 y 6): ");
Scanner scn = new Scanner(System.in);
colores = scn.nextInt();
while(colores < 2 || colores > 6)
{
System.out.println("Invalid matrix size. Re-enter ");
}
return colores;
}
public static int aleatorio(int colores) {
int l = (int) (Math.floor(Math.random()*(colores-2)) + 2);
return l;
}
I would really appreciate some help because I don't know how to continue, Thanks.
You call numeroColores() in a for-loop in a for-loop, so you are of course asked multiple times for it.
Btw. you have an endless loop if you type in 1 or smaller or 7 or bigger with constantly getting the same line printed out and not asking for new input
Try this code to generate the random value between 2 and 6
public static int aleatorio(int colores) {
int l = 0;
while(l < 2 || l > 6) {
l = (int) (Math.floor(Math.random()*(colores-2)) + 2);
}
return l;
}
I have implemented a recursive radix-2 DIT FFT in Java, and a regular DFT to verify my results from the FFT, but the results from the two differ and I cannot seem to figure it out. Both are fed the entire array with the apply()-methods, start and stop index is 0 and data.length respectively. The DFT version looks correct with a nice peak at bin 50 while the FFT one is full of garbage. What am I doing wrong?
This is the FFT implementation (adapted from http://www.engineeringproductivitytools.com/stuff/T0001/PT04.HTM "A Recursive DIT FFT Routine.", I verified by comparing to the pseudo code at https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Pseudocode):
public class DITFFT2 extends Transform {
public float[] apply(float[] data, int startIndex, int stopIndex) throws IllegalArgumentException {
int N;
float[] filteredData;
Complex[] complexData;
Complex[] filteredComplexData;
if (stopIndex < startIndex) {
throw new IllegalArgumentException("stopIndex cannot be lower than startIndex!");
}
if (stopIndex < 0 || startIndex < 0) {
throw new IllegalArgumentException("Index cannot be negative!");
}
N = stopIndex - startIndex;
filteredData = new float[N];
complexData = new Complex[N];
for (int i = startIndex; i < stopIndex; i++) {
complexData[i-startIndex] = new Complex(data[i], 0.0f);
}
filteredComplexData = transform(complexData, N);
for (int i = 0; i < N; i++) {
filteredData[i] = filteredComplexData[i].abs();
}
return filteredData;
}
public Complex[] transform(Complex[] data, int N) {
Complex x;
Complex[] result = new Complex[N];
if (N == 1) {
result[0] = data[0];
} else {
Complex[] fe = new Complex[N/2];
Complex[] fo = new Complex[N/2];
for (int i = 0; i < N/2; i++) {
fe[i] = data[2*i];
fo[i] = data[2*i+1];
}
Complex[] Fe = transform(fe, N / 2);
Complex[] Fo = transform(fo, N / 2);
for (int k = 0; k < N/2; k++) {
x = Fo[k].copy();
x.mul(getTwiddleFactor(k, N));
result[k] = Fe[k].copy();
result[k].add(x);
result[k+N/2] = Fe[k].copy();
result[k+N/2].sub(x);
}
}
return result;
}
private Complex getTwiddleFactor(int k, int N) {
return new Complex(1.0f, (float)(-2.0f * Math.PI * k / (float)N));
}
}
And this is the DFT implementation:
public class DFT extends Transform {
public float[] apply(float[] data, int startIndex, int stopIndex) throws IllegalArgumentException {
int N;
float[] filteredData;
Complex[] complexData;
Complex[] filteredComplexData;
if (stopIndex < startIndex) {
throw new IllegalArgumentException("stopIndex cannot be lower than startIndex!");
}
if (stopIndex < 0 || startIndex < 0) {
throw new IllegalArgumentException("Index cannot be negative!");
}
N = stopIndex - startIndex;
filteredData = new float[N];
complexData = new Complex[N];
filteredComplexData = new Complex[N];
for (int i = startIndex; i < stopIndex; i++) {
complexData[i-startIndex] = new Complex(data[i], 0.0f);
filteredComplexData[i-startIndex] = new Complex(0.0f, 0.0f);
}
for (int k = 0; k < N; k++) {
for (int n = 0; n < N; n++) {
Complex c = complexData[n].copy();
filteredComplexData[k].add(c.mul(new Complex(1.0f, (float)(-2*Math.PI*n*k/(float)N))));
}
}
for (int i = 0; i < N; i++) {
filteredData[i] = filteredComplexData[i].abs();
}
return filteredData;
}
}
Now, both seems to give the correct answer for [8.0, 4.0, 8.0, 0.0], which is [20.0, 4.0j, 12.0, -4.0j]. But if I feed them a sine produced by:
mBuffer = new float[1024];
float sampleRate = 1000.0f;
float frequency = 50.0f;
for (int i = 0; i < mBuffer.length; i++) {
mBuffer[i] = (float)(0.5*Math.sin(2*Math.PI*i*frequency/sampleRate));
}
The implementation of Complex for reference:
public final class Complex {
public float mR, mTheta;
public Complex() {
mR = 0.0f;
mTheta = 0.0f;
}
public Complex(float r, float theta) {
mR = r;
mTheta = theta;
}
public Complex copy() {
return new Complex(mR, mTheta);
}
public Complex add(Complex c) {
float real, imag;
real = (float)(mR * Math.cos(mTheta) + c.mR * Math.cos(c.mTheta));
imag = (float)(mR * Math.sin(mTheta) + c.mR * Math.sin(c.mTheta));
mR = (float)Math.sqrt(Math.pow(real, 2) + Math.pow(imag, 2));
if (real != 0.0f) {
mTheta = (float)Math.atan(imag / real);
} else {
mTheta = (float)(imag > 0.0f ? Math.PI/2.0f : Math.PI*3.0f/2.0f);
}
return this;
}
public Complex sub(Complex c) {
float real, imag;
real = (float)(mR * Math.cos(mTheta) - c.mR * Math.cos(c.mTheta));
imag = (float)(mR * Math.sin(mTheta) - c.mR * Math.sin(c.mTheta));
mR = (float)Math.sqrt(Math.pow(real, 2) + Math.pow(imag, 2));
if (real != 0.0f) {
mTheta = (float)Math.atan(imag / real);
} else {
mTheta = (float)(imag > 0.0f ? Math.PI/2.0f : Math.PI*3.0f/2.0f);
}
return this;
}
public Complex mul(Complex c) {
mR = mR * c.mR;
mTheta = mTheta + c.mTheta;
return this;
}
public Complex div(Complex c) {
mR = mR / c.mR;
mTheta = mTheta - c.mTheta;
return this;
}
public Complex pow(float exp) {
mTheta = mTheta * exp;
mR = (float)Math.pow(mR, exp);
return this;
}
public float abs() {
return mR;
}
public float getRealPart() {
return (float)(mR * Math.cos(mTheta));
}
public float getImagPart() {
return (float)(mR * Math.sin(mTheta));
}
public String toStringRectangular() {
float real, imag;
StringBuilder sb = new StringBuilder();
real = (float)(mR * Math.cos(mTheta));
imag = (float)(mR * Math.sin(mTheta));
sb.append(real);
if (imag >= 0) {
sb.append(" + ");
} else {
sb.append(" - ");
}
sb.append(Math.abs(imag));
sb.append("i");
return sb.toString();
}
public String toStringExponential() {
StringBuilder sb = new StringBuilder();
sb.append(mR);
sb.append(" * e ^ ");
sb.append(mTheta);
sb.append("i");
return sb.toString();
}
public String toString() {
return toStringExponential() + " [ " + toStringRectangular() + " ] ";
}
public static Complex[] getInitializedArray(int size) {
Complex[] arr = new Complex[size];
for (int i = 0; i < arr.length; i++) {
arr[i] = new Complex(0.0f, 0.0f);
}
return arr;
}
}
Your FFT implementation seems reasonable. However there is an issue with the use of Math.atan (which return a value within the [-pi/2,pi/2], instead of the whole [-pi,pi] range) in Complex's add and sub.
To resolve this issue you should be using:
mTheta = (float)Math.atan2(imag, real);
I'm trying to figure out how to go about using these methods to complete this assignment but I'm still relatively new with Java and don't know where to go with it. The array file we have is: 2D Array
Here is the assignment: Assignment
I am just looking for some insight on the math and what to use to get started with these methods. I'm not asking for anyone to do my homework! Thanks for any help in advance!
Here is what I have so far:
public static void main(String[] args) throws FileNotFoundException {
File skyimage = new File("skyimage.txt");
Scanner scan = new Scanner(skyimage);
int r, c;
r = scan.nextInt();
c = scan.nextInt();
int sky[][] = new int[r][c];
for(r = 0; r < sky.length; r++){
for(c = 0; c < sky[r].length; c++)
sky[r][c] = scan.nextInt();
}
printArray(sky);
lightSource(sky, c);
}//end main
private static void printArray(int[][] sky) {
for(int r = 0; r < sky.length; r++){
for(int c = 0; c < sky[r].length; c++){
System.out.printf("%5d", sky[r][c]);
}
System.out.println();
}
}
public static void lightSource(int sky[][], int n){
Point[] lightPoint = new Point[n];
for(int r = 0; r < sky.length; r++){
for(int c = 0; c < sky[r].length; c++){
new Point(r, c);
}
}
System.out.println("The brightest interior point is located at: " + lightPoint);
}//end method
public static void darkSource(){
}//end method
public static void filterImage(){
}//end method
public static void negativeImage(){
}//end method
Once you have read the input, all you need is just a few utility methods
(like sum, getNeighbours and isValidPoint) and a few loops.
Here is a sketch (not a full-blown solution).
In it I have hard-coded the sample sky input.
import java.awt.Point;
import java.util.ArrayList;
import java.util.List;
public class Test045 {
private static int[][] sky = {
{10,2,2},
{10,5,1},
{1,2,2}
};
public static void main(String[] args) {
Point min = null;
Point max = null;
Integer sumMin = null;
Integer sumMax = null;
Integer s = null;
for (int i=0; i<sky.length; i++){
for (int j=0; j<sky[0].length; j++){
s=sum(getNeighbours(i, j));
if (sumMin==null || sumMin > s){
min = new Point(i,j);
sumMin = s;
}
if (sumMax==null || sumMax < s){
max = new Point(i,j);
sumMax = s;
}
}
}
System.out.println("Max Light at: " + max.x + ", " + max.y +
" ; MAX Light = " + sumMax);
System.out.println("Min Light at: " + min.x + ", " + min.y +
" ; MIN Light = " + sumMin);
}
private static int sum(List<Point> lst){
int sum = 0;
for (Point p : lst){
sum += sky[p.x][p.y];
}
return sum;
}
private static List<Point> getNeighbours(int ip, int jp){
List<Point> lst = new ArrayList<Point>();
for (int i=-1; i<=1; i++){
for (int j=-1; j<=1; j++){
if (isValidPoint(ip+i, jp+j)){
lst.add(new Point(ip+i, jp+j));
}
}
}
return lst;
}
private static boolean isValidPoint(int i, int j){
return
i >= 0 && i < sky.length &&
j >= 0 && j < sky[0].length;
}
}
Is there a way to do what the title suggests? What I'm trying to do is create a table of experience values required to level up like so:
int level1 = 50;
int level2 = level1 + (level1 * 0.1);
int level3 = level2 + (level2 * 0.1);
But I want to get to around 100 levels... Is there a way to quickly define x number of usable int values?
Assuming you're continuing that formula...
int[] array = new int[100];
array[0] = 50;
for (int i = 1; i < 100; i++) {
array[i] = (int) (array[i - 1] * 1.1);
}
Use this approach:
public class Level
{
public Level()
{
int[] levels = new int[100]; // 100 Levels
initializeLevels(levels);
printLevels(levels);
}
private void initializeLevels(int[] levels)
{
levels[0] = 50;
for (int i = 1; i < 100; i++)
{
levels[i] = (int) (levels[i - 1] * 1.1f);
}
}
private void printLevels(int[] levels)
{
for (int i = 0; i < 100; i++)
{
System.out.println("Level " + (i + 1) + " = " + levels[i]);
}
}
public static void main(String[] args)
{
new Level();
}
}