001 package edu.jhu.mb.ernst.model.synapse; 002 003 import java.util.*; 004 005 import edu.jhu.mb.ernst.model.*; 006 007 /*********************************************************************** 008 * Modulated Synapse implementation. 009 * 010 * <p> 011 * This implementation optimizes read performance at the expense of write 012 * performance. The accessor methods are fast but the modulation factor 013 * mutator methods are slow. Use this implementation when the modulation 014 * factors are changed infrequently relative to the number of times the 015 * modulated weight is accessed. 016 * </p> 017 * 018 * <p> 019 * This implementation conserves memory by using lazy initialization and 020 * by releasing memory allocated to internal data structures when empty. 021 * </p> 022 * 023 * <p> 024 * ModulatedSynapseImp can be used as the default implementation for 025 * accessor interface Synapse because its memory consumption and read 026 * access performance is similar to MutableSynapseImp when modulation is 027 * not used. 028 * </p> 029 * 030 * @see 031 * MutableSynapseImp 032 * 033 * @version 034 * $Date: 2012-04-15 13:47:26 -0500 (Sun, 15 Apr 2012) $ 035 * $Rev: 9 $ 036 * $Author: croft $ 037 * @since 038 * 2012-02-19 039 * @author 040 * David Wallace Croft 041 ***********************************************************************/ 042 public final class ModulatedSynapseImp 043 implements ModulatedSynapse 044 //////////////////////////////////////////////////////////////////////// 045 //////////////////////////////////////////////////////////////////////// 046 { 047 048 private final int 049 targetNeuronIndex; 050 051 private final byte 052 type; 053 054 private final double 055 unmodulatedWeight; 056 057 // 058 059 private Map<String, Double> 060 modulationFactorMap; 061 062 private float 063 modulatedWeight; 064 065 //////////////////////////////////////////////////////////////////////// 066 //////////////////////////////////////////////////////////////////////// 067 068 public ModulatedSynapseImp ( 069 final int targetNeuronIndex, 070 final byte type, 071 final float unmodulatedWeight ) 072 //////////////////////////////////////////////////////////////////////// 073 { 074 this.targetNeuronIndex = targetNeuronIndex; 075 076 this.type = type; 077 078 this.unmodulatedWeight = unmodulatedWeight; 079 080 modulatedWeight = unmodulatedWeight; 081 } 082 083 //////////////////////////////////////////////////////////////////////// 084 // accessor methods 085 //////////////////////////////////////////////////////////////////////// 086 087 @Override 088 public int getTargetNeuronIndex ( ) 089 //////////////////////////////////////////////////////////////////////// 090 { 091 return targetNeuronIndex; 092 } 093 094 @Override 095 public byte getType ( ) 096 //////////////////////////////////////////////////////////////////////// 097 { 098 return type; 099 } 100 101 @Override 102 public float getWeight ( ) 103 //////////////////////////////////////////////////////////////////////// 104 { 105 return modulatedWeight; 106 } 107 108 //////////////////////////////////////////////////////////////////////// 109 // mutator methods 110 //////////////////////////////////////////////////////////////////////// 111 112 @Override 113 public void clearModulationFactors ( ) 114 //////////////////////////////////////////////////////////////////////// 115 { 116 if ( modulationFactorMap != null ) 117 { 118 modulationFactorMap = null; 119 } 120 121 modulatedWeight = ( float ) unmodulatedWeight; 122 } 123 124 @Override 125 public void setModulationFactor ( 126 final String name, 127 final Double peakFactor ) 128 //////////////////////////////////////////////////////////////////////// 129 { 130 if ( peakFactor == null ) 131 { 132 if ( modulationFactorMap == null ) 133 { 134 // The weight does not need to be recomputed. 135 136 return; 137 } 138 139 final Double oldValue = modulationFactorMap.remove ( name ); 140 141 if ( modulationFactorMap.size ( ) == 0 ) 142 { 143 modulationFactorMap = null; 144 } 145 146 if ( oldValue == null ) 147 { 148 // The weight does not need to be recomputed. 149 150 return; 151 } 152 } 153 else 154 { 155 if ( modulationFactorMap == null ) 156 { 157 modulationFactorMap = new HashMap<String, Double> ( ); 158 } 159 160 modulationFactorMap.put ( name, peakFactor ); 161 } 162 163 modulatedWeight = ( float ) unmodulatedWeight; 164 165 if ( modulationFactorMap != null ) 166 { 167 for ( final Double value : modulationFactorMap.values ( ) ) 168 { 169 modulatedWeight *= value.doubleValue ( ); 170 } 171 } 172 } 173 174 //////////////////////////////////////////////////////////////////////// 175 //////////////////////////////////////////////////////////////////////// 176 177 @Override 178 public int compareTo ( final Synapse other ) 179 //////////////////////////////////////////////////////////////////////// 180 { 181 return SynapseLib.compareTo ( this, other ); 182 } 183 184 @Override 185 public String toString ( ) 186 //////////////////////////////////////////////////////////////////////// 187 { 188 return SynapseLib.toString ( this ); 189 } 190 191 //////////////////////////////////////////////////////////////////////// 192 //////////////////////////////////////////////////////////////////////// 193 }