Commit 6840e09f authored by David A.. Werner's avatar David A.. Werner
Browse files

Manduca.py pep8

parent a7a9ae8f
......@@ -2,167 +2,180 @@ import numpy as np
import StringIO
import functools
class ManducaDeformityError(Exception):
def __init__(self, message):
self.message = message
def __str__(self):
return repr(self.message)
class Manduca(object):
def __init__(self, legs, muscles, time_step):
self._legs = self._muscles = None
self.legs = np.copy(legs)
self.muscles = np.copy(muscles)
self._time_step = time_step
self._fitness = None
self.check_consistancy()
@property
def legs(self):
return self._legs
@legs.setter
def legs(self, legs):
new_legs = np.array(legs)
if self._legs:
if new_legs.shape != self._legs.shape:
msg = 'Ill-defined leg shape. Expected {} but got {}'
e = msg.format(self._legs.shape, new_legs.shape)
def __init__(self, legs, muscles, time_step):
self._legs = self._muscles = None
self.legs = np.copy(legs)
self.muscles = np.copy(muscles)
self._time_step = time_step
self._fitness = None
self.check_consistancy()
@property
def legs(self):
return self._legs
@legs.setter
def legs(self, legs):
new_legs = np.array(legs)
if self._legs:
if new_legs.shape != self._legs.shape:
msg = 'Ill-defined leg shape. Expected {} but got {}'
e = msg.format(self._legs.shape, new_legs.shape)
raise(ManducaDeformityError(e))
self._legs = new_legs
self._fitness = None
@property
def muscles(self):
return self._muscles
@muscles.setter
def muscles(self, muscles):
new_muscles = np.array(muscles)
if self._muscles:
if new_muscles.shape != self._muscles.shape:
msg = 'Ill-defined muscles shape. Expected {} but got {}'
e = msg.format(self._muscles.shape, new_muscles.shape)
raise(ManducaDeformityError(e))
self._muscles = new_muscles
self._fitness = None
@property
def time_step(self):
return self._time_step
@time_step.setter
def time_step(self, time_step):
self._time_step = time_step
self._fitness = None
@property
def num_legs(self):
return self.legs.shape[1]
@property
def num_muscles(self):
return self.muscles.shape[1]
@property
def num_time_steps(self):
leg_ts, muscle_ts = self.legs.shape[0], self.muscles.shape[0]
if leg_ts != muscle_ts:
msg = 'Arbitrary number of time-steps. {} in legs, {} in muscles'
e = msg.format(leg_ts, muscle_ts)
raise(ManducaDeformityError(e))
self._legs = new_legs
self._fitness = None
@property
def muscles(self):
return self._muscles
@muscles.setter
def muscles(self, muscles):
new_muscles = np.array(muscles)
if self._muscles:
if new_muscles.shape != self._muscles.shape:
msg = 'Ill-defined muscles shape. Expected {} but got {}'
e = msg.format(self._muscles.shape, new_muscles.shape)
return leg_ts
@property
def fitness(self):
if (self._fitness is None):
results = self.simulate()
self._fitness = 0
return (self._fitness)
@property
def initial_position(self):
return np.arange(self.num_legs)*500
def check_consistancy(self):
if self.num_muscles != self.num_legs - 1:
msg = 'Ill-defined manduca has {} legs and {} muscles'
e = msg.format(self.num_legs, self.num_muscles)
raise(ManducaDeformityError(e))
self._muscles = new_muscles
self._fitness = None
@property
def time_step(self):
return self._time_step
@time_step.setter
def time_step(self, time_step):
self._time_step = time_step
self._fitness = None
@property
def num_legs(self):
return self.legs.shape[1]
@property
def num_muscles(self):
return self.muscles.shape[1]
@property
def num_time_steps(self):
leg_ts, muscle_ts = self.legs.shape[0], self.muscles.shape[0]
if leg_ts != muscle_ts:
msg = 'Arbitrary number of time-steps. {} in legs, {} in muscles'
e = msg.format(leg_ts, muscle_ts)
raise(ManducaDeformityError(e))
return leg_ts
@property
def fitness(self):
if (self._fitness is None):
results = self.simulate()
self._fitness = 0
return (self._fitness)
@property
def initial_position(self):
return np.arange(self.num_legs)*500
def check_consistancy(self):
if self.num_muscles != self.num_legs - 1:
msg = 'Ill-defined manduca has {} legs and {} muscles'
e = msg.format(self.num_legs, self.num_muscles)
raise(ManducaDeformityError(e))
# Make sure the number of time steps is consistant
self.num_time_steps
def __repr__(self):
output = StringIO.StringIO()
output.write("\n legs | muscles")
for leg_t, musc_t in zip(self.legs,self.muscles):
leg_str = " ".join("{:>1}".format(int(l)) for l in leg_t)
musc_str = " ".join("{:>3}".format(int(m)) for m in musc_t)
output.write("\n{} | {}".format(leg_str, musc_str))
val = output.getvalue()
output.close()
return val
def __eq__ (self, other):
return (self.time_step==other.time_step and
np.array_equal(self.legs, other.legs) and
np.array_equal(self.muscles,other.muscles) )
def __ne__(self, other):
return (self.time_step!=other.time_step or
not(np.array_equal(self.legs, other.legs)) or
not(np.array_equal(self.muscles,other.muscles)))
def __hash__(self):
return hash(self.legs.tostring()+self.muscles.tostring()+str(self.time_step))
def simulate(self):
pass
def save(self, file_name, compressed=True):
if compressed:
save_fn = np.savez_compressed
else:
save_fn = np.savez
save_fn(file_name, legs=self.legs, muscles=self.muscles,
time_step=self.time_step,fitness=self._fitness)
@classmethod
def load(cls, file_name, *other_params, **kwargs):
try:
results = np.load(file_name)
legs = results['legs']
muscles = results['muscles']
time_step = results['time_step']
args =[]
for param in other_params:
args.append(results[param])
new_manduca = cls(legs, muscles, time_step, *args, **kwargs)
if 'fitness' in results:
new_manduca._fitness = np.asscalar(results['fitness'])
return new_manduca
except (IOError, ValueError) as e:
print('Error loading {} from file {}'.format(cls.__name__, file_name))
raise(e)
def clone(self):
return (self.__class__(np.copy(self.legs), np.copy(self.muscles)))
# Make sure the number of time steps is consistant
self.num_time_steps
def __repr__(self):
output = StringIO.StringIO()
output.write("\n legs | muscles")
for leg_t, musc_t in zip(self.legs, self.muscles):
leg_str = " ".join("{:>1}".format(int(l)) for l in leg_t)
musc_str = " ".join("{:>3}".format(int(m)) for m in musc_t)
output.write("\n{} | {}".format(leg_str, musc_str))
val = output.getvalue()
output.close()
return val
def __eq__(self, other):
return (self.time_step == other.time_step and
np.array_equal(self.legs, other.legs) and
np.array_equal(self.muscles, other.muscles))
def __ne__(self, other):
return (self.time_step != other.time_step or
not(np.array_equal(self.legs, other.legs)) or
not(np.array_equal(self.muscles, other.muscles)))
def __hash__(self):
leg_str, m_str = self.legs.tostring(), self.muscles.tostring()
t_str = str(self.time_step)
manduca_str = leg_str + m_str + t_str
return hash(manduca_str)
def simulate(self):
pass
def save(self, file_name, compressed=True):
if compressed:
save_fn = np.savez_compressed
else:
save_fn = np.savez
save_fn(file_name, legs=self.legs, muscles=self.muscles,
time_step=self.time_step, fitness=self._fitness)
@classmethod
def load(cls, file_name, *other_params, **kwargs):
try:
results = np.load(file_name)
legs = results['legs']
muscles = results['muscles']
time_step = results['time_step']
args = []
for param in other_params:
args.append(results[param])
new_manduca = cls(legs, muscles, time_step, *args, **kwargs)
if 'fitness' in results:
new_manduca._fitness = np.asscalar(results['fitness'])
return new_manduca
except (IOError, ValueError) as e:
msg = 'Error loading {} from file {}'
print(msg.format(cls.__name__, file_name))
raise(e)
def clone(self):
return (self.__class__(np.copy(self.legs), np.copy(self.muscles)))
class SimpleManduca(Manduca):
"""A Manduca that has legs and muscles that are either ON/OFF"""
def __init__(self, legs, muscles, time_step, muscle_strength=None):
super(SimpleManduca, self).__init__(legs, muscles, time_step)
assert ((self.legs==1)|(self.legs==0)).all(), "Legs must be 0 or 1"
if muscle_strength is None:
assert self.muscles.max() != 0, "Cannot detemine muscle_strength when all values are 0"
muscle_strength = self.muscles.max()
assert ((self.muscles==0)|(self.muscles==muscle_strength)).all(), \
"Muscles must be 0 or {}".format(muscle_strength)
@staticmethod
def random_individual(num_legs, time_segments, time_step, muscle_strength=100, rng=np.random):
legs = rng.choice([0,1],size=(time_segments, num_legs))
muscles = rng.choice([0,muscle_strength],size=(time_segments, num_legs-1))
return SimpleManduca(legs, muscles, time_step, muscle_strength=muscle_strength)
"""A Manduca that has legs and muscles that are either ON/OFF"""
def __init__(self, legs, muscles, time_step, muscle_strength=None):
super(SimpleManduca, self).__init__(legs, muscles, time_step)
locked_legs, unlocked_legs = self.legs == 1, self.legs == 0
assert (locked_legs | unlocked_legs).all(), "Legs must be 0 or 1"
if muscle_strength is None:
msg = "Cannot detemine muscle_strength when all values are 0"
assert self.muscles.max() != 0, msg
muscle_strength = self.muscles.max()
musc_on, musc_off = self.muscles == 0, self.muscles == muscle_strength
msg = "Muscles must be 0 or {}".format(muscle_strength)
assert (musc_on | musc_off).all(), msg
@staticmethod
def random_individual(num_legs, time_segments, time_step, **kwargs):
musc_stren = kwargs.pop(muscle_strength, 100)
rng = kwargs.pop('rng', np.random)
legs = rng.choice([0, 1], size=(time_segments, num_legs))
muscles = rng.choice([0, muscle_strength],
size=(time_segments, num_legs-1))
return SimpleManduca(legs, muscles, time_step,
muscle_strength=muscle_strength)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment