The program below is a substantial simplification of one that worked but in spite of hours of effort I can't identify why the following bug occurs: Everything works as expected except that when the line "if behavior[2,0] > t then goright(brain,stimulus) end" is executed, the line "stimulus.each {|n| stimulus[n,0]=0 }" does NOT reset all of the elements of the stimulus vector to 0 as it does otherwise. Instead the "1" placed there by the previous trip through the "for c in (0..$Choices)" remains thereby generating double behaviors (both a left and right turn) when only one is expected. I've commented out everything that I believe is irrelevant yet it still happens.
class Matrix
def []=(i, j, x)
@rows[i][j] = x
end
end #code to allow putting individual elements in matrix at i,j
brain= Matrix[ [90,0,0,0,0,0,0,0,0,0,0],
[0,90,0,10,10,10,10,0,0,0,0],
[0,0,90,10,10,10,10,0,0,0,0] ]
longmem=Matrix[ [90,0,0,0,0,0,0,0,0,0,0],
[0,90,0,10,10,10,10,0,0,0,0],
[0,0,90,10,10,10,10,0,0,0,0] ]
stimulus=Matrix.column_vector([0,0,0,0,0,0,0,0,0,0,0])
behavior=Matrix.column_vector([0,0,0])
t=89 # t=threshold
# decay_rate=2
$Stimmax=10
$Behavmax=2
$Choices=2
# begin defining behavioral methods
def learn(ix, brain, stimulus)
psp=20
for j in (8..$Stimmax)
if brain[ix,j] > 0 then brain[ix,j] = 20 end #modified hunting for bug
end # for j
end # learn
#def positive_fixer(brain,stimulus,longmem,energy)
# reinf=0.9
# for i in (0..$Behavmax)
# for j in (7..$Stimmax)
# if longmem[i,j]>0 then longmem[i,j] =(reinf*(brain[i,j]-longmem[i,j])).round end
# end
# end
# learn(0, brain, stimulus)
#end #positive fixer comment out in bug hunt
def goleft(brain,stimulus)
puts " Left Turn"
learn(1,brain,stimulus)
end # def left
def goright(brain,stimulus)
puts " Right Turn"
learn(2,brain,stimulus)
end # def right
# end defining behavioral methods
# begin MAIN PROGRAM
for c in (0..$Choices)
stimulus.each {|n| stimulus[n,0]=0 }
# SET ALL STIMS TO O
puts "Should by all 0s"
stimulus.to_a.each {|r| puts r.inspect} # aid in bug hunt
stimulus[rand(1..2),0]= 1
#add print stimulus vector for debugging
puts "Should by just a single 1"
stimulus.to_a.each {|r| puts r.inspect} # aid in bug hunt
# memory decay
#for i in (0..$Behavmax)
#for j in (7..$Stimmax)
# if brain[i,j]>longmem[i,j] then brain[i,j] =-(brain[i,j]-longmem[i,j])/decay_rate end
# if brain[i,j]<longmem[i,j] then brain[i,j] =-1*((brain[i,j] longmem[i,j])/decay_rate) end
#end #for j
#end #for i
# memory decay commented out in search for bug
behavior=brain*stimulus
if behavior[0,0] > t then positive_fixer(brain, stimulus, longmem, energy) end
if behavior[1,0] > t then goleft(brain,stimulus) end
if behavior[2,0] > t then goright(brain,stimulus) end
end #for c
puts
brain.to_a.each {|r| puts r.inspect}
# end main program```
CodePudding user response:
Not sure why the code Karl Knechtel pointed out doesn't work but the simple code in my last comment above does.
CodePudding user response:
the line "stimulus.each {|n| stimulus[n,0]=0 }" does NOT reset all of the elements of the stimulus vector to 0 as it does otherwise
One of the way how to reset vector:
require 'matrix'
vector = Matrix.column_vector([1, 2, 3])
# => Matrix[[1], [2], [3]]
vector.each_with_index { |_, i| vector[i, 0] = 0 }
# => Matrix[[0], [0], [0]]
So you need to use each_with_index
instead of each