001    /*
002     * Copyright 2011 Christian Kumpe http://kumpe.de/christian/java
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *     http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package de.kumpe.hadooptimizer.examples.neurons;
017    
018    import java.io.Serializable;
019    import java.util.ArrayList;
020    import java.util.Collection;
021    
022    public class Neuron implements Value {
023            private static final long serialVersionUID = 1L;
024    
025            public static class Input implements Serializable {
026                    private static final long serialVersionUID = 1L;
027    
028                    private final Value output;
029                    private double weight;
030    
031                    private Input(final Value output) {
032                            this.output = output;
033                    }
034    
035                    public double getWeight() {
036                            return weight;
037                    }
038    
039                    public void setWeight(final double weight) {
040                            this.weight = weight;
041                    }
042            }
043    
044            private final Collection<Input> inputs = new ArrayList<Input>();
045            private final double threshold;
046            private final double a;
047    
048            public Neuron() {
049                    this(0, 1);
050            }
051    
052            public Neuron(final double threshold, final double a) {
053                    this.threshold = threshold;
054                    this.a = a;
055            }
056    
057            public Input addInput(final Value output) {
058                    final Input input = new Input(output);
059                    inputs.add(input);
060                    return input;
061            }
062    
063            public Input addInput(final Value output, final double weight) {
064                    final Input input = addInput(output);
065                    input.setWeight(weight);
066                    return input;
067            }
068    
069            @Override
070            public double value() {
071                    double sum = 0;
072                    for (final Input input : inputs) {
073                            sum += input.weight * input.output.value();
074                    }
075                    return activationFunction(sum - threshold);
076            }
077    
078            private double activationFunction(final double value) {
079                    return 1 / (1 + Math.exp(-a * value));
080            }
081    }