I am busy with transmitting a Bluetooth Low Energy UUID via my Raspberry Pi. That setup is done and works to a satisfactory extent.
But now my personal objective is to make a very simple android app, that catches this UUID and displays it on the android screen.
So after some browsing around, I found this Radius Network iBeacon package with a iBeacon.java code in it.
I am very new to Android Studio. For the life of me, I can't seem to debug that iBeacon.java code to my android (Jellybean) phone..
So basically the directory for that code looks like this:
android-ibeacon-service/src/com/radiusnetworks/ibeacon/client/iBeacon.java
I guess the first directory part is the package?
I have tried importing the whole thing, but it shows so many things not working,
I have also tried just importing the iBeacon.java code.. But that doesn't run to my phone..
The iBeacon.java looks like this:
/**
* Radius Networks, Inc.
* http://www.radiusnetworks.com
*
* #author David G. Young
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package com.radiusnetworks.ibeacon;
import java.util.Collections;
import com.radiusnetworks.ibeacon.client.RangedIBeacon;
import android.util.Log;
/**
* The <code>IBeacon</code> class represents a single hardware iBeacon detected by
* an Android device.
*
* <pre>An iBeacon is identified by a three part identifier based on the fields
* proximityUUID - a string UUID typically identifying the owner of a
* number of ibeacons
* major - a 16 bit integer indicating a group of iBeacons
* minor - a 16 bit integer identifying a single iBeacon</pre>
*
* An iBeacon sends a Bluetooth Low Energy (BLE) advertisement that contains these
* three identifiers, along with the calibrated tx power (in RSSI) of the
* iBeacon's Bluetooth transmitter.
*
* This class may only be instantiated from a BLE packet, and an RSSI measurement for
* the packet. The class parses out the three part identifier, along with the calibrated
* tx power. It then uses the measured RSSI and calibrated tx power to do a rough
* distance measurement (the accuracy field) and group it into a more reliable buckets of
* distance (the proximity field.)
*
* #author David G. Young
* #see Region#matchesIBeacon(IBeacon iBeacon)
*/
public class IBeacon {
/**
* Less than half a meter away
*/
public static final int PROXIMITY_IMMEDIATE = 1;
/**
* More than half a meter away, but less than four meters away
*/
public static final int PROXIMITY_NEAR = 2;
/**
* More than four meters away
*/
public static final int PROXIMITY_FAR = 3;
/**
* No distance estimate was possible due to a bad RSSI value or measured TX power
*/
public static final int PROXIMITY_UNKNOWN = 0;
final private static char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
private static final String TAG = "IBeacon";
/**
* A 16 byte UUID that typically represents the company owning a number of iBeacons
* Example: E2C56DB5-DFFB-48D2-B060-D0F5A71096E0
*/
protected String proximityUuid;
/**
* A 16 bit integer typically used to represent a group of iBeacons
*/
protected int major;
/**
* A 16 bit integer that identifies a specific iBeacon within a group
*/
protected int minor;
/**
* An integer with four possible values representing a general idea of how far the iBeacon is away
* #see #PROXIMITY_IMMEDIATE
* #see #PROXIMITY_NEAR
* #see #PROXIMITY_FAR
* #see #PROXIMITY_UNKNOWN
*/
protected Integer proximity;
/**
* A double that is an estimate of how far the iBeacon is away in meters. This name is confusing, but is copied from
* the iOS7 SDK terminology. Note that this number fluctuates quite a bit with RSSI, so despite the name, it is not
* super accurate. It is recommended to instead use the proximity field, or your own bucketization of this value.
*/
protected Double accuracy;
/**
* The measured signal strength of the Bluetooth packet that led do this iBeacon detection.
*/
protected int rssi;
/**
* The calibrated measured Tx power of the iBeacon in RSSI
* This value is baked into an iBeacon when it is manufactured, and
* it is transmitted with each packet to aid in the distance estimate
*/
protected int txPower;
/**
* If multiple RSSI samples were available, this is the running average
*/
protected Double runningAverageRssi = null;
/**
* #see #accuracy
* #return accuracy
*/
public double getAccuracy() {
if (accuracy == null) {
accuracy = calculateAccuracy(txPower, runningAverageRssi != null ? runningAverageRssi : rssi );
}
return accuracy;
}
/**
* #see #major
* #return major
*/
public int getMajor() {
return major;
}
/**
* #see #minor
* #return minor
*/
public int getMinor() {
return minor;
}
/**
* #see #proximity
* #return proximity
*/
public int getProximity() {
if (proximity == null) {
proximity = calculateProximity(getAccuracy());
}
return proximity;
}
/**
* #see #rssi
* #return rssi
*/
public int getRssi() {
return rssi;
}
/**
* #see #txPower
* #return txPowwer
*/
public int getTxPower() {
return txPower;
}
/**
* #see #proximityUuid
* #return proximityUuid
*/
public String getProximityUuid() {
return proximityUuid;
}
#Override
public int hashCode() {
return minor;
}
/**
* Two detected iBeacons are considered equal if they share the same three identifiers, regardless of their distance or RSSI.
*/
#Override
public boolean equals(Object that) {
if (!(that instanceof IBeacon)) {
return false;
}
IBeacon thatIBeacon = (IBeacon) that;
return (thatIBeacon.getMajor() == this.getMajor() && thatIBeacon.getMinor() == this.getMinor() && thatIBeacon.getProximityUuid() == thatIBeacon.getProximityUuid());
}
/**
* Construct an iBeacon from a Bluetooth LE packet collected by Android's Bluetooth APIs
*
* #param scanData The actual packet bytes
* #param rssi The measured signal strength of the packet
* #return An instance of an <code>IBeacon</code>
*/
public static IBeacon fromScanData(byte[] scanData, int rssi) {
if (((int)scanData[5] & 0xff) == 0x4c &&
((int)scanData[6] & 0xff) == 0x00 &&
((int)scanData[7] & 0xff) == 0x02 &&
((int)scanData[8] & 0xff) == 0x15) {
// yes! This is an iBeacon
}
else if (((int)scanData[5] & 0xff) == 0x2d &&
((int)scanData[6] & 0xff) == 0x24 &&
((int)scanData[7] & 0xff) == 0xbf &&
((int)scanData[8] & 0xff) == 0x16) {
// this is an Estimote beacon
IBeacon iBeacon = new IBeacon();
iBeacon.major = 0;
iBeacon.minor = 0;
iBeacon.proximityUuid = "00000000-0000-0000-0000-000000000000";
iBeacon.txPower = -55;
return iBeacon;
}
else {
// This is not an iBeacon
Log.d(TAG, "This is not an iBeacon advertisment. The bytes I see are: "+bytesToHex(scanData));
return null;
}
IBeacon iBeacon = new IBeacon();
iBeacon.major = (scanData[25] & 0xff) * 0x100 + (scanData[26] & 0xff);
iBeacon.minor = (scanData[27] & 0xff) * 0x100 + (scanData[28] & 0xff);
iBeacon.txPower = (int)scanData[29]; // this one is signed
iBeacon.rssi = rssi;
// AirLocate:
// 02 01 1a 1a ff 4c 00 02 15 # Apple's fixed iBeacon advertising prefix
// e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profile uuid
// 00 00 # major
// 00 00 # minor
// c5 # The 2's complement of the calibrated Tx Power
// Estimote:
// 02 01 1a 11 07 2d 24 bf 16
// 394b31ba3f486415ab376e5c0f09457374696d6f7465426561636f6e00000000000000000000000000000000000000000000000000
byte[] proximityUuidBytes = new byte[16];
System.arraycopy(scanData, 9, proximityUuidBytes, 0, 16);
String hexString = bytesToHex(proximityUuidBytes);
StringBuilder sb = new StringBuilder();
sb.append(hexString.substring(0,8));
sb.append("-");
sb.append(hexString.substring(8,12));
sb.append("-");
sb.append(hexString.substring(12,16));
sb.append("-");
sb.append(hexString.substring(16,20));
sb.append("-");
sb.append(hexString.substring(20,32));
iBeacon.proximityUuid = sb.toString();
return iBeacon;
}
protected IBeacon(IBeacon otherIBeacon) {
this.major = otherIBeacon.major;
this.minor = otherIBeacon.minor;
this.accuracy = otherIBeacon.accuracy;
this.proximity = otherIBeacon.proximity;
this.rssi = otherIBeacon.rssi;
this.proximityUuid = otherIBeacon.proximityUuid;
this.txPower = otherIBeacon.txPower;
}
protected IBeacon() {
}
protected static double calculateAccuracy(int txPower, double rssi) {
if (rssi == 0) {
return -1.0; // if we cannot determine accuracy, return -1.
}
Log.d(TAG, "calculating accuracy based on rssi of "+rssi);
double ratio = rssi*1.0/txPower;
if (ratio < 1.0) {
return Math.pow(ratio,10);
}
else {
double accuracy = (0.89976)*Math.pow(ratio,7.7095) + 0.111;
Log.d(TAG, " avg rssi: "+rssi+" accuracy: "+accuracy);
return accuracy;
}
}
protected static int calculateProximity(double accuracy) {
if (accuracy < 0) {
return PROXIMITY_UNKNOWN;
// is this correct? does proximity only show unknown when accuracy is negative? I have seen cases where it returns unknown when
// accuracy is -1;
}
if (accuracy < 0.5 ) {
return IBeacon.PROXIMITY_IMMEDIATE;
}
// forums say 3.0 is the near/far threshold, but it looks to be based on experience that this is 4.0
if (accuracy <= 4.0) {
return IBeacon.PROXIMITY_NEAR;
}
// if it is > 4.0 meters, call it far
return IBeacon.PROXIMITY_FAR;
}
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int v;
for ( int j = 0; j < bytes.length; j++ ) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
How can I solve this mystery? :)
I'm the one who wrote that IBeacon.java code about two years ago. Since then it has been rewritten and is now available in a ready to run Android Studio reference app here:
https://github.com/AltBeacon/android-beacon-library-reference
You do have to make one change to it to get it to detect iBeacons. See here for that change:
Is this the correct layout to detect iBeacons with AltBeacon's Android Beacon Library?
Related
I was trying to follow the example here: http://docs.oracle.com/javase/tutorial/displayCode.html?code=http://docs.oracle.com/javase/tutorial/essential/concurrency/examples/ForkBlur.java
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveAction;
import javax.imageio.ImageIO;
/**
* ForkBlur implements a simple horizontal image blur. It averages pixels in the
* source array and writes them to a destination array. The sThreshold value
* determines whether the blurring will be performed directly or split into two
* tasks.
*
* This is not the recommended way to blur images; it is only intended to
* illustrate the use of the Fork/Join framework.
*/
public class ForkBlur extends RecursiveAction {
private int[] mSource;
private int mStart;
private int mLength;
private int[] mDestination;
private int mBlurWidth = 15; // Processing window size, should be odd.
public ForkBlur(int[] src, int start, int length, int[] dst) {
mSource = src;
mStart = start;
mLength = length;
mDestination = dst;
}
// Average pixels from source, write results into destination.
protected void computeDirectly() {
int sidePixels = (mBlurWidth - 1) / 2;
for (int index = mStart; index < mStart + mLength; index++) {
// Calculate average.
float rt = 0, gt = 0, bt = 0;
for (int mi = -sidePixels; mi <= sidePixels; mi++) {
int mindex = Math.min(Math.max(mi + index, 0), mSource.length - 1);
int pixel = mSource[mindex];
rt += (float) ((pixel & 0x00ff0000) >> 16) / mBlurWidth;
gt += (float) ((pixel & 0x0000ff00) >> 8) / mBlurWidth;
bt += (float) ((pixel & 0x000000ff) >> 0) / mBlurWidth;
}
// Re-assemble destination pixel.
int dpixel = (0xff000000)
| (((int) rt) << 16)
| (((int) gt) << 8)
| (((int) bt) << 0);
mDestination[index] = dpixel;
}
}
protected static int sThreshold = 10000;
#Override
protected void compute() {
if (mLength < sThreshold) {
computeDirectly();
return;
}
int split = mLength / 2;
invokeAll(new ForkBlur(mSource, mStart, split, mDestination),
new ForkBlur(mSource, mStart + split, mLength - split,
mDestination));
}
// Plumbing follows.
public static void main(String[] args) throws Exception {
String srcName = "awesome_face.jpg";
File srcFile = new File(srcName);
BufferedImage image = ImageIO.read(srcFile);
System.out.println("Source image: " + srcName);
BufferedImage blurredImage = blur(image);
String dstName = "blurred-awesome-face.jpg";
File dstFile = new File(dstName);
ImageIO.write(blurredImage, "jpg", dstFile);
System.out.println("Output image: " + dstName);
}
public static BufferedImage blur(BufferedImage srcImage) {
int w = srcImage.getWidth();
int h = srcImage.getHeight();
int[] src = srcImage.getRGB(0, 0, w, h, null, 0, w);
int[] dst = new int[src.length];
System.out.println("Array size is " + src.length);
System.out.println("Threshold is " + sThreshold);
int processors = Runtime.getRuntime().availableProcessors();
System.out.println(Integer.toString(processors) + " processor"
+ (processors != 1 ? "s are " : " is ")
+ "available");
ForkBlur fb = new ForkBlur(src, 0, src.length, dst);
ForkJoinPool pool = new ForkJoinPool();
long startTime = System.currentTimeMillis();
pool.invoke(fb);
long endTime = System.currentTimeMillis();
System.out.println("Image blur took " + (endTime - startTime) +
" milliseconds.");
BufferedImage dstImage =
new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
dstImage.setRGB(0, 0, w, h, dst, 0, w);
return dstImage;
}
}
I copied this code to my computer and compiled and ran it and received the following error:
Source image: awesome_face.jpg
Array size is 100000
Threshold is 10000
4 processors are available
Image blur took 19 milliseconds.
Exception in thread "main" javax.imageio.IIOException: Invalid argument to native writeImage
at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeImage(Native Method)
at com.sun.imageio.plugins.jpeg.JPEGImageWriter.writeOnThread(JPEGImageWriter.java:1058)
at com.sun.imageio.plugins.jpeg.JPEGImageWriter.write(JPEGImageWriter.java:360)
at javax.imageio.ImageWriter.write(ImageWriter.java:615)
at javax.imageio.ImageIO.doWrite(ImageIO.java:1612)
at javax.imageio.ImageIO.write(ImageIO.java:1536)
at ForkBlur.main(ForkBlur.java:112)
It looks like the problem is at line 112 in the ImageIO.write() method. I looked at the API for this method here: http://docs.oracle.com/javase/7/docs/api/javax/imageio/ImageIO.html From my understanding the arguments to write() are okay but something is really messed up at runtime.
Does anyone know what is wrong with this program?
Regards,
...
I am using javax.sound to make sounds, however when you play it they have some sort of noise in background, which even overcomes the sound if you play few notes at once. Here is the code:
public final static double notes[] = new double[] {130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185,
196, 207.65, 220, 233.08, 246.94, 261.63, 277.18, 293.66,
311.13, 329.63, 349.23, 369.99, 392, 415.3, 440, 466.16,
493.88, 523.25, 554.37};
public static void playSound(int note, int type) throws LineUnavailableException { //type 0 = sin, type 1 = square
Thread t = new Thread() {
public void run() {
try {
int sound = (int) (notes[note] * 100);
byte[] buf = new byte[1];
AudioFormat af = new AudioFormat((float) sound, 8, 1, true,
false);
SourceDataLine sdl;
sdl = AudioSystem.getSourceDataLine(af);
sdl = AudioSystem.getSourceDataLine(af);
sdl.open(af);
sdl.start();
int maxi = (int) (1000 * (float) sound / 1000);
for (int i = 0; i < maxi; i++) {
double angle = i / ((float) 44100 / 440) * 2.0
* Math.PI;
double val = 0;
if (type == 0) val = Math.sin(angle)*100;
if (type == 1) val = square(angle)*50;
buf[0] = (byte) (val * (maxi - i) / maxi);
sdl.write(buf, 0, 1);
}
sdl.drain();
sdl.stop();
sdl.close();
} catch (LineUnavailableException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
};
t.start();
}
public static double square (double angle){
angle = angle % (Math.PI*2);
if (angle > Math.PI) return 1;
else return 0;
}
This code is from here: https://stackoverflow.com/a/1932537/3787777
In this answer I will refer to 1) your code, 2) better approach (IMHO:) and 3) playing of two notes in the same time.
Your code
First, the sample rate should not depend on note frequency. Therefore try:
AudioFormat(44100,...
Next, use 16 bit sampling (sounds better!). Here is your code that plays simple tone without noise - but I would use it bit differently (see later). Please look for the comments:
Thread t = new Thread() {
public void run() {
try {
int sound = (440 * 100); // play A
AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
SourceDataLine sdl;
sdl = AudioSystem.getSourceDataLine(af);
sdl.open(af, 4096 * 2);
sdl.start();
int maxi = (int) (1000 * (float) sound / 1000); // should not depend on notes frequency!
byte[] buf = new byte[maxi * 2]; // try to find better len!
int i = 0;
while (i < maxi * 2) {
// formula is changed to be simple sine!!
double val = Math.sin(Math.PI * i * 440 / 44100);
short s = (short) (Short.MAX_VALUE * val);
buf[i++] = (byte) s;
buf[i++] = (byte) (s >> 8); // little endian
}
sdl.write(buf, 0, maxi);
sdl.drain();
sdl.stop();
sdl.close();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
};
t.start();
Proposal for better code
Here is a simplified version of your code that plays some note (frequency) without noise. I like it better as we first create array of doubles, which are universal values. These values can be combined together, or stored or further modified. Then we convert them to (8bit or 16bit) samples values.
private static byte[] buffer = new byte[4096 * 2 / 3];
private static int bufferSize = 0;
// plays a sample in range (-1, +1).
public static void play(SourceDataLine line, double in) {
if (in < -1.0) in = -1.0; // just sanity checks
if (in > +1.0) in = +1.0;
// convert to bytes - need 2 bytes for 16 bit sample
short s = (short) (Short.MAX_VALUE * in);
buffer[bufferSize++] = (byte) s;
buffer[bufferSize++] = (byte) (s >> 8); // little Endian
// send to line when buffer is full
if (bufferSize >= buffer.length) {
line.write(buffer, 0, buffer.length);
bufferSize = 0;
}
// todo: be sure that whole buffer is sent to line!
}
// prepares array of doubles, not related with the sampling value!
private static double[] tone(double hz, double duration) {
double amplitude = 1.0;
int N = (int) (44100 * duration);
double[] a = new double[N + 1];
for (int i = 0; i <= N; i++) {
a[i] = amplitude * Math.sin(2 * Math.PI * i * hz / 44100);
}
return a;
}
// finally:
public static void main(String[] args) throws LineUnavailableException {
AudioFormat af = new AudioFormat(44100, 16, 1, true, false);
SourceDataLine sdl = AudioSystem.getSourceDataLine(af);
sdl.open(af, 4096 * 2);
sdl.start();
double[] tones = tone(440, 2.0); // play A for 2 seconds
for (double t : tones) {
play(sdl, t);
}
sdl.drain();
sdl.stop();
sdl.close();
}
Sounds nice ;)
Play two notes in the same time
Just combine two notes:
double[] a = tone(440, 1.0); // note A
double[] b = tone(523.25, 1.0); // note C (i hope:)
for (int i = 0; i < a.length; i++) {
a[i] = (a[i] + b[i]) / 2;
}
for (double t : a) {
play(sdl, t);
}
Remember that with double array you can combine and manipulate your tones - i.e. to make composition of tone sounds that are being played in the same time. Of course, if you add 3 tones, you need to normalize the value by dividing with 3 and so on.
Ding Dong :)
The answer has already been provided, but I want to provide some information that might help understanding the solution.
Why 44100?
44.1 kHz audio is widely used, due to this being the sampling rate used in CDs. Analog audio is recorded by sampling it 44,100 times per second (1 cycle per second = 1 Hz), and then these samples are used to reconstruct the audio signal when playing it back. The reason behind the selection of this frequency is rather complex; and unimportant for this explanation. That said, the suggestion of using 22000 is not very good because that frequency is too close to the human hearing range (20Hz - 20kHz). You would want to use a sampling rate higher than 40kHz for good sound quality. I think mp4 uses 96kHz.
Why 16-bit?
The standard used for CDs is 44.1kHz/16-bit. MP4 uses 96kHz/24-bit. The sample rate refers to how many X-bit samples are recorded every second. CD-quality sampling uses 44,100 16-bit samples to reproduce sound.
Why is this explanation important?
The thing to remember is that you are trying to produce digital sound (not analog). This means that these bits and bytes have to be processed by an audio CODEC. In hardware, an audio CODEC is a device that encodes analog audio as digital signals and decodes digital back into analog. For audio outputs, the digitized sound must go through a Digital-to-Analog Converter (DAC) in order for proper sound to come out of the speakers. Two of the most important characteristics of a DAC are its bandwidth and its signal-to-noise ratio and the actual bandwidth of a DAC is characterized primarily by its sampling rate.
Basically, you can't use an arbitrary sampling rate because the audio will not be reproduced well by your audio device for the reasons stated above. When in doubt, check your computer hardware and find out what your CODEC supports.
need some help here. Working on "Classes and Object-Oriented Development" and could use some help with both my logic and code for a question in the textbook.
Question: I am asked to Modify my previous example of my Rectangle class to override the equals() and toString() methods. Two rectangles are equal when they both have the same length and width.
My approach: I tried to change it to do this, and then decided it would be easier to compare by areas, rather than comparing both by width and length, so below is what I have so far. Let me know if you have any ideas to help. There is a previous example of the equals() method that compares a circle's radius but isnt helping when comparing 2 different things. Thanks before hand all ! If your wondering why they are all not their own separate files, I haven't gotten there in the chapter yet so it's alot to look at I know ;P
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package chapter8javaExamples;
/**
*
* #author Eric
*/
public class Rectangle {
private double length, width;
/**
* constructor
* pre: none
* post: A rectangle class is created.
*/
public Rectangle() {
length = 2; //default length
width = 4; //default width
}
/**
* constructor
* pre: none
* post: A rectangle object is created with length and width.
*/
public Rectangle (double l, double w) {
length = l;
width = w;
}
/**
* Changes the length of the rectangle
* pre: none
* post: Length has been changed.
*/
public void setLength (double newLength) {
length = newLength;
}
/**
* Changes the width of the rectangle.
* pre: none
* post: Width has been changed.
*/
public void setWidth (double newWidth) {
width = newWidth;
}
/**
* Returns the length of the rectangle.
* pre: none
* post: The length of the rectangle has been returned.
*/
public double getLength() {
return(length);
}
/**
* Returns the width of the rectangle.
* pre: none
* post: The width of the rectangle has been returned.
*/
public double getWidth() {
return(width);
}
/**
* Returns the area of rectangle
* pre: none
* post: The area of the rectangle is returned
*/
public double area() {
double triArea;
triArea = length * width;
return(triArea);
}
/**
* Returns the perimeter of the rectangle
* pre: none
* post: The perimeter of the rectangle is returned
*/
public double perimeter() {
double triPer;
triPer = length + width + length + width;
return(triPer);
}
/**
* Displays the formula for area of a rectangle.
* pre: none
* post: The formula is displayed.
*/
public static void displayAreaFormula(){
System.out.println("The formula for the area of a rectangle is a=l*w");
}
/**
* Determines if the object is equal to another
* Circle object.
* pre: c is a Circle object.
* post: true has been returned if the objects have
* the same radii, false otherwise.
*/
public boolean equals(Object r) {
Rectangle testObj = (Rectangle) r;
Rectangle testObj2 = (Rectangle) r2;
if (testObj.getArea() == area && testObj2.getArea == area()) {
return(true);
} else {
return(false);
}
}
/**
* Returns a String that represents the Circle object.
* pre: none
* post: A string representing the Circle object has
* been returned.
*/
public String toString(){
String rectangleString;
rectangleString = "Rectangle has the Area " + length*width;
return(rectangleString);
}
/**
*
* #param args
*/
public static void main(String [] args){
Rectangle spot = new Rectangle();
Rectangle spot2 = new Rectangle(5, 9);
System.out.println("Area is: " + spot.area());
System.out.println("Perimeter: " + spot.perimeter());
Rectangle.displayAreaFormula();
}
}
I don't think that comparing the areas is a good idea in the equals method, because a rectangle that is 2x8 would equal a rectangle that is 4x4, because both areas are 16. This contradicts your requirement:
Two rectangles are equal when they both have the same length and width.
Here, your r2 variable is undefined. But beyond that, the equals method shouldn't compare two other objects, it should compare this object to another object.
You should return true if the r object is a Rectangle and this rectangle's length matches the other rectangle's length and this rectangle's width matches the other rectangle's width.
Your equals method should always have the following structure:
public boolean equals(Object r) {
if(r == null || !r instanceof Rectangle) return false;
// rest of the code
}
This is because you don't want to perform operations on a null-reference (which would throws errors), and this can't equals null anyway. Secondly: if r is not an instance of the rectangle class, we can quit before having to perform other operations, because a Rectangle would not equal a String, or a Circle.
Now, to get to your question: if you want to check on equality purely by width and length, I would write the method like this:
public boolean equals(Object r) {
if(r == null || !r instanceof Rectangle) return false;
if(length == r.length && width == w.width) return true;
return false;
}
This compares the width and length. If they are both equal, two rectangles are equal. You are comparing the area, but this could give false positives. Take this example:
Rectangle r1;
Rectangle r2;
r1.width = 10;
r1.length = 5;
r2.width = 5;
r2.length = 10;
Your code would produce a positive, while these rectangles are orientated differently.
Two rectangles are equal when they have both same length and width.
Are these following rectangles the same?
and
Hey! Both have the same area don't they?
So in short, no you have use && to see if the length and breadth of both are equal or you could compare the .toString()s of both rectangles to see if they are exact.
To add to the other answers (read those first)
If you are comparing "physical" objects (a block of wood for example) then you might want to compare length to width and width to length as well. The orientation a user inputs might be submitted differently for two of the same objects. Consider this when reading your requirements.
I found an example online which contains a method that back propagates the error and adjusts the weights. I was wondering how this exactly works and what weight update algorithm is used. Could it be gradient descent?
/**
* all output propagate back
*
* #param expectedOutput
* first calculate the partial derivative of the error with
* respect to each of the weight leading into the output neurons
* bias is also updated here
*/
public void applyBackpropagation(double expectedOutput[]) {
// error check, normalize value ]0;1[
for (int i = 0; i < expectedOutput.length; i++) {
double d = expectedOutput[i];
if (d < 0 || d > 1) {
if (d < 0)
expectedOutput[i] = 0 + epsilon;
else
expectedOutput[i] = 1 - epsilon;
}
}
int i = 0;
for (Neuron n : outputLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double ak = n.getOutput();
double ai = con.leftNeuron.getOutput();
double desiredOutput = expectedOutput[i];
double partialDerivative = -ak * (1 - ak) * ai
* (desiredOutput - ak);
double deltaWeight = -learningRate * partialDerivative;
double newWeight = con.getWeight() + deltaWeight;
con.setDeltaWeight(deltaWeight);
con.setWeight(newWeight + momentum * con.getPrevDeltaWeight());
}
i++;
}
// update weights for the hidden layer
for (Neuron n : hiddenLayer) {
ArrayList<Connection> connections = n.getAllInConnections();
for (Connection con : connections) {
double aj = n.getOutput();
double ai = con.leftNeuron.getOutput();
double sumKoutputs = 0;
int j = 0;
for (Neuron out_neu : outputLayer) {
double wjk = out_neu.getConnection(n.id).getWeight();
double desiredOutput = (double) expectedOutput[j];
double ak = out_neu.getOutput();
j++;
sumKoutputs = sumKoutputs
+ (-(desiredOutput - ak) * ak * (1 - ak) * wjk);
}
double partialDerivative = aj * (1 - aj) * ai * sumKoutputs;
double deltaWeight = -learningRate * partialDerivative;
double newWeight = con.getWeight() + deltaWeight;
con.setDeltaWeight(deltaWeight);
con.setWeight(newWeight + momentum * con.getPrevDeltaWeight());
}
}
}
It seems to me this solution uses stochastic gradient descent. The main difference between it and the regular gradient decent is that the gradient is approximated for each example instead of calculating it for all examples and then selecting the best direction. This is the usual approach to implementing backpropagtion and even has some advantages to gradient decent(can avoid some local minima). I believe the article also exaplains what is the idea and there are also a lot of other articles that explain the main idea behind back-propagation.
This ugly looking article seems to be describing exactly the same version of the algorithm: http://www.speech.sri.com/people/anand/771/html/node37.html. I have the same formulas in my university papers, but regretfully: a) they are not available online; b) they are in language you will not understand.
As for gradient descent, the algorithm resembles gradient descent, but is not guaranteed to reach optimal position. In each step change is done over the network edges changing their values so that the training example value's probability increases.
I am modifying a graph implementation to compute the all pairs shortest path matrix using Floyd's algorithm. The graph has both adjacency linked list and matrix implementations. For now I am using adjacency matrix because it its needed for this algorithm.
abstract public class GraphMatrix<V,E> extends AbstractStructure<V> implements Graph<V,E>{
/**
* Number of vertices in graph.
*/
protected int size; // allocation size for graph
/**
* The edge data. Every edge appears on one (directed)
* or two (undirected) locations within graph.
*/
protected Object data[][]; // matrix - array of arrays
/**
* Translation between vertex labels and vertex structures.
*/
protected Map<V,GraphMatrixVertex<V>> dict; // labels -> vertices
/**
* List of free vertex indices within graph.
*/
protected List<Integer> freeList; // available indices in matrix
/**
* Whether or not graph is directed.
*/
protected boolean directed; // graph is directed
/**
* Constructor of directed/undirected GraphMatrix. Protected constructor.
*
* #param size Maximum size of graph.
* #param dir True if graph is to be directed.
*/
protected GraphMatrix(int size, boolean dir)
{
this.size = size; // set maximum size
directed = dir; // fix direction of edges
// the following constructs a size x size matrix
data = new Object[size][size];
// label to index translation table
dict = new Hashtable<V,GraphMatrixVertex<V>>(size);
// put all indices in the free list
freeList = new SinglyLinkedList<Integer>();
for (int row = size-1; row >= 0; row--)
freeList.add(new Integer(row));
}
.
.
.
public Object[][] AllPairsShortestPath()
{
//First, data array needs to be copied to a new array so that it is not corrupted.
Object[][] weight_matrix = data.clone();
for(int k = 0; k < size; k++)
{
for(int i = 0; i < size; i++)
{
for(int j = 0; j < size; j++)
{
if((weight_matrix + weight_matrix[k][j])<weight_matrix[i][j])
{
//New shorter path is found
}
}
}
}
return weight_matrix;
}
My question is how can I reference the weight_matrix elements so that they can be compared?
Here is the edge class that is in the Object matrix:
public class Edge<V,E>
{
/**
* Two element array of vertex labels.
* When necessary, first element is source.
*/
protected V here, there; // labels of adjacent vertices
/**
* Label associated with edge. May be null.
*/
protected E label; // edge label
/**
* Whether or not this edge has been visited.
*/
protected boolean visited; // this edge visited
/**
* Whether or not this edge is directed.
*/
protected boolean directed; // this edge directed
/**
* Construct a (possibly directed) edge between two labeled
* vertices. When edge is directed, vtx1 specifies source.
* When undirected, order of vertices is unimportant. Label
* on edge is any type, and may be null.
* Edge is initially unvisited.
*
* #post edge associates vtx1 and vtx2; labeled with label
* directed if "directed" set true
*
* #param vtx1 The label of a vertex (source if directed).
* #param vtx2 The label of another vertex (destination if directed).
* #param label The label associated with the edge.
* #param directed True iff this edge is directed.
*/
public Edge(V vtx1, V vtx2, E label,
boolean directed)
{
here = vtx1;
there = vtx2;
this.label = label;
visited = false;
this.directed = directed;
}
/**
* Returns the first vertex (or source if directed).
*
* #post returns first node in edge
*
* #return A vertex; if directed, the source.
*/
public V here()
{
return here;
}
/**
* Returns the second vertex (or source if undirected).
*
* #post returns second node in edge
*
* #return A vertex; if directed, the destination.
*/
public V there()
{
return there;
}
/**
* Sets the label associated with the edge. May be null.
*
* #post sets label of this edge to label
*
* #param label Any object to label edge, or null.
*/
public void setLabel(E label)
{
this.label = label;
}
/**
* Get label associated with edge.
*
* #post returns label associated with this edge
*
* #return The label found on the edge.
*/
public E label()
{
return label;
}
/**
* Test and set visited flag on vertex.
*
* #post visits edge, returns whether previously visited
*
* #return True iff edge was visited previously.
*/
public boolean visit()
{
boolean was = visited;
visited = true;
return was;
}
/**
* Check to see if edge has been visited.
*
* #post returns true iff edge has been visited
*
* #return True iff the edge has been visited.
*/
public boolean isVisited()
{
return visited;
}
/**
* Check to see if edge is directed.
*
* #post returns true iff edge is directed
*
* #return True iff the edge has been visited.
*/
public boolean isDirected()
{
return directed;
}
/**
* Clear the visited flag associated with edge.
*
* #post resets edge's visited flag to initial state
*/
public void reset()
{
visited = false;
}
/**
* Returns hashcode associated with edge.
*
* #post returns suitable hashcode
*
* #return An integer code suitable for hashing.
*/
public int hashCode()
{
if (directed) return here().hashCode()-there().hashCode();
else return here().hashCode()^there().hashCode();
}
/**
* Test for equality of edges. Undirected edges are equal if
* they connect the same vertices. Directed edges must have same
* direction.
*
* #post returns true iff edges connect same vertices
*
* #param o The other edge.
* #return True iff this edge is equal to other edge.
*/
public boolean equals(Object o)
{
Edge<?,?> e = (Edge<?,?>)o;
return ((here().equals(e.here()) &&
there().equals(e.there())) ||
(!directed &&
(here().equals(e.there()) &&
there().equals(e.here()))));
}
/**
* Construct a string representation of edge.
*
* #post returns string representation of edge
*
* #return String representing edge.
*/
public String toString()
{
StringBuffer s = new StringBuffer();
s.append("<Edge:");
if (visited) s.append(" visited");
s.append(" "+here());
if (directed) s.append(" ->");
else s.append(" <->");
s.append(" "+there()+">");
return s.toString();
}
}
I guess
((weight_matrix + weight_matrix[k][j])<weight_matrix[i][j])
is not what you want. IIRC, Floyd's as follows:
((weight_matrix[i][k] + weight_matrix[k][j])<weight_matrix[i][j])
IF YOUR weight_matrix were a matrix of weights (take a look here for more floyd). Size, in this implementation, would be the number of vertices you got on the graph.
If each edge had a weight, you could do
(( ((Edge)weight_matrix[i][k]).getValue() + ((Edge)weight_matrix[k][j]).getValue()) < ((Edge)weight_matrix[i][j]).getValue())
If all edge weights are equal, you could tell getValue() to return 1 always, and voilá.