Method: String#search

Defined in:
lib/mgmg/search.rb

#search(para, target, opt: Mgmg::Option.new) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/mgmg/search.rb', line 71

def search(para, target, opt: Mgmg::Option.new)
	org_cut_exp = opt.cut_exp
	opt = opt.dup.set_default(self)
	opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
	begin
		opt.comp_min = comp_search(para, target, opt.smith_max, opt:)
	rescue Mgmg::SearchCutException
		foo = opt.irep.para_call(para, opt.smith_max, opt.comp_max)
		raise Mgmg::SearchCutException, "#{self} could not reach target=#{target} until (smith_max, comp_max)=(#{opt.smith_max}, #{opt.comp_max}), which yields #{foo.comma3}"
	end
	opt.smith_max = smith_search(para, target, opt.comp_min, opt: opt_nocut)
	opt.smith_min = smith_search(para, target, opt.comp_max, opt: opt_nocut)
	raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.comp_min)
	opt.comp_max = comp_search(para, target, opt.smith_min, opt:)
	ret = nil
	exp = Mgmg.exp(opt.smith_min, opt.comp_max)
	opt.cut_exp, ret = exp, [opt.smith_min, opt.comp_max] if exp <= opt.cut_exp
	exp = Mgmg.exp(opt.smith_max, opt.comp_min)
	opt.cut_exp, ret = exp, [opt.smith_max, opt.comp_min] if ( exp < opt.cut_exp || (ret.nil? && exp==opt.cut_exp) )
	eo = opt.irep.eo_para(para)
	comps = Mgmg.fib_init(opt.comp_min, opt.comp_max)
	values = comps.map do |comp|
		r, e = eval_comp(para, target, comp, opt_nocut, eo)
		opt.cut_exp, ret = e, r if e < opt.cut_exp
		e
	end
	while 3 < comps[3]-comps[0]
		if values[1] <= values[2]
			comp = comps[0] + comps[2]-comps[1]
			comps = [comps[0], comp, comps[1], comps[2]]
			r, e = eval_comp(para, target, comp, opt_nocut, eo)
			opt.cut_exp, ret = e, r if e < opt.cut_exp
			values = [values[0], e, values[1], values[2]]
		else
			comp = comps[1] + comps[3]-comps[2]
			comps = [comps[1], comps[2], comp, comps[3]]
			r, e = eval_comp(para, target, comp, opt_nocut, eo)
			opt.cut_exp, ret = e, r if e < opt.cut_exp
			values = [values[1], values[2], e, values[3]]
		end
	end
	exp_best = opt.cut_exp
	values = values.filter(&:finite?)
	diff = values.max-values.min
	if 0 < diff
		opt.cut_exp = exp_best + diff*opt.fib_ext[0]
		(comps[0]-1).downto(opt.comp_min) do |comp|
			exp_best, ret = fine(exp_best, ret, para, target, comp, opt, eo)
		rescue Mgmg::SearchCutException
			break
		end
		(comps[3]+1).upto(opt.comp_max) do |comp|
			exp_best, ret = fine(exp_best, ret, para, target, comp, opt, eo)
		rescue Mgmg::SearchCutException
			break
		end
	end
	if ret.nil?
		max = opt.irep.para_call(para, *find_max(para, org_cut_exp, opt:))
		raise Mgmg::SearchCutException, "the maximum output with given cut_exp=#{org_cut_exp.comma3} is #{max.comma3}, which does not reach given target=#{target.comma3}"
	end
	ret
end