Class: Mgmg::TPolynomial

Inherits:
Object
  • Object
show all
Defined in:
lib/mgmg/poly.rb

Constant Summary collapse

Cache =
Hash.new
ParamIndex =
Hash.new

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mat, kind, star, main_m, sub_m) ⇒ TPolynomial

Returns a new instance of TPolynomial.



5
6
7
# File 'lib/mgmg/poly.rb', line 5

def initialize(mat, kind, star, main_m, sub_m)
	@mat, @kind, @star, @main, @sub = mat, kind, star, main_m, sub_m
end

Instance Attribute Details

#kindObject

Returns the value of attribute kind.



8
9
10
# File 'lib/mgmg/poly.rb', line 8

def kind
  @kind
end

#mainObject

Returns the value of attribute main.



8
9
10
# File 'lib/mgmg/poly.rb', line 8

def main
  @main
end

#matObject

Returns the value of attribute mat.



8
9
10
# File 'lib/mgmg/poly.rb', line 8

def mat
  @mat
end

#starObject

Returns the value of attribute star.



8
9
10
# File 'lib/mgmg/poly.rb', line 8

def star
  @star
end

#subObject

Returns the value of attribute sub.



8
9
10
# File 'lib/mgmg/poly.rb', line 8

def sub
  @sub
end

Class Method Details

.build(str, para, left_associative: true, include_system_equips: true) ⇒ Object



332
333
334
335
336
337
338
339
340
341
# File 'lib/mgmg/poly.rb', line 332

def build(str, para, left_associative: true, include_system_equips: true)
	str = Mgmg.check_string(str)
	_para = ParamIndex[para]
	if _para.nil?
		raise ArgumentError, "unknown parameter symbol `#{para.inspect}' given"
	end
	stack = []
	stack, str = build_sub0(stack, str, _para) if include_system_equips
	build_sub(stack, str, _para, left_associative)
end

.compose(main, sub, para) ⇒ Object



316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/mgmg/poly.rb', line 316

def compose(main, sub, para)
	main_k, sub_k = main.kind, sub.kind
	main_s, sub_s = main.star, sub.star
	main_main, sub_main = main.main, sub.main
	main_sub, sub_sub = main.sub, sub.sub
	para = ParamIndex[para]
	
	if Equip9[main_k][para] == 0
		c = 0.quo(1)
	else
		c = ( 100 + Equip9[main_k][para] - Equip9[sub_k][para] + Material9[main_main][para] - Material9[sub_main][para] +
			(main_s-sub_s)*5 - ( ( main_main==sub_main && main_main != 9 ) ? 30 : 0 ) ).quo( main_k==sub_k ? 40000 : 20000 )
	end
	mat = main.mat.padd(sub.mat.pprod(Mat.h_array(c*Equip9[main_k][para], c)))
	new(mat, main_k, main_s+sub_s, main_sub, sub_main)
end

.from_equip(equip, para) ⇒ Object



297
298
299
# File 'lib/mgmg/poly.rb', line 297

def from_equip(equip, para)
	new(Mat.new(1, 1, equip.para[ParamIndex[para]]), equip.kind, equip.star, equip.main, equip.sub)
end

.smith(str, para) ⇒ Object



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/mgmg/poly.rb', line 300

def smith(str, para)
	key = [str.freeze, para].freeze
	return Cache[key].dup if Cache.has_key?(key)
	unless m = /\A(.+)\((.+\d+),?(.+\d+)\)\Z/.match(str)
		raise ArgumentError.new("given string `#{str}' is unparsable as a smithing recipe")
	end
	kind = EquipIndex[m[1].to_sym]
	main_m, main_s, main_mc = Mgmg.parse_material(m[2])
	sub_m, sub_s, sub_mc = Mgmg.parse_material(m[3])
	para = ParamIndex[para]
	
	c = ( Equip9[kind][para] * Main9[main_m][para] ).cdiv(100).quo( main_mc==sub_mc ? 200 : 100 )
	ret = new(Mat.v_array(c*Sub9[sub_m][para], c), kind, (main_s+sub_s).div(2), main_mc, sub_mc)
	Cache.store(key, ret.freeze)
	ret.dup
end

Instance Method Details

#+(other) ⇒ Object



142
143
144
145
146
# File 'lib/mgmg/poly.rb', line 142

def +(other)
	other = self.coerce(other)[0] unless other.kind_of?(self.class)
	mat = @mat.padd(other.mat)
	self.class.new(mat, 28, 0, 12, 12)
end

#-(other) ⇒ Object



147
148
149
150
151
# File 'lib/mgmg/poly.rb', line 147

def -(other)
	other = self.coerce(other)[0] unless other.kind_of?(self.class)
	mat = @mat.padd(other.mat.scalar(-1))
	self.class.new(mat, 28, 0, 12, 12)
end

#-@Object



137
138
139
140
141
# File 'lib/mgmg/poly.rb', line 137

def -@
	ret = self.dup
	ret.mat.scalar!(-1)
	ret
end

#<(other) ⇒ Object



214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/mgmg/poly.rb', line 214

def <(other)
	foo = self-other
	(foo.mat.row_size-1).downto(0) do |s|
		(foo.mat.col_size-1).downto(0) do |c|
			bar = foo.mat.body[s][c]
			if bar < 0
				return true
			elsif 0 < bar
				return false
			end
		end
	end
	false
end

#<=(other) ⇒ Object



228
229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/mgmg/poly.rb', line 228

def <=(other)
	foo = self-other
	(foo.mat.row_size-1).downto(0) do |s|
		(foo.mat.col_size-1).downto(0) do |c|
			bar = foo.mat.body[s][c]
			if bar < 0
				return true
			elsif 0 < bar
				return false
			end
		end
	end
	true
end

#<=>(other) ⇒ Object



280
281
282
283
284
285
286
287
288
# File 'lib/mgmg/poly.rb', line 280

def <=>(other)
	if self == other
		0
	elsif self < other
		-1
	else
		1
	end
end

#==(other) ⇒ Object



270
271
272
273
274
275
276
277
278
279
# File 'lib/mgmg/poly.rb', line 270

def ==(other)
	foo = self-other
	(foo.mat.row_size-1).downto(0) do |s|
		(foo.mat.col_size-1).downto(0) do |c|
			bar = foo.mat.body[s][c]
			return false if bar != 0
		end
	end
	true
end

#>(other) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/mgmg/poly.rb', line 242

def >(other)
	foo = other-self
	(foo.mat.row_size-1).downto(0) do |s|
		(foo.mat.col_size-1).downto(0) do |c|
			bar = foo.mat.body[s][c]
			if bar < 0
				return true
			elsif 0 < bar
				return false
			end
		end
	end
	false
end

#>=(other) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'lib/mgmg/poly.rb', line 256

def >=(other)
	foo = other-self
	(foo.mat.row_size-1).downto(0) do |s|
		(foo.mat.col_size-1).downto(0) do |c|
			bar = foo.mat.body[s][c]
			if bar < 0
				return true
			elsif 0 < bar
				return false
			end
		end
	end
	true
end

#[](i, j) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
# File 'lib/mgmg/poly.rb', line 199

def [](i, j)
	if (i < 0 && @mat.body.size < -i) || (j < 0 && @mat.body[0].size < -j)
		raise IndexError, "(#{i}, #{j}) is out of (#{@mat.body.size}, #{@mat.body[0].size})"
	end
	begin
		ret = @mat.body[i][j]
	rescue NoMethodError
		return 0
	end
	ret.nil? ? 0 : ret
end

#coerce(other) ⇒ Object



211
212
213
# File 'lib/mgmg/poly.rb', line 211

def coerce(other)
	[self.class.new(Mat.new(1, 1, other), 28, 0, 12, 12), self]
end

#comp_eff(smith, comp = smith) ⇒ Object



192
193
194
# File 'lib/mgmg/poly.rb', line 192

def comp_eff(smith, comp=smith)
	partial_derivative('c').evaluate(smith, comp).quo(4*(comp-1))
end

#eff(smith, comp = smith) ⇒ Object



195
196
197
# File 'lib/mgmg/poly.rb', line 195

def eff(smith, comp=smith)
	[smith_eff(smith, comp), comp_eff(smith, comp)]
end

#evaluate(smith, comp = smith) ⇒ Object



12
13
14
15
16
# File 'lib/mgmg/poly.rb', line 12

def evaluate(smith, comp=smith)
	@mat.map_with_index do |e, i, j|
		e * (smith**i) * (comp**j)
	end.sum
end

#initialize_copy(obj) ⇒ Object



9
10
11
# File 'lib/mgmg/poly.rb', line 9

def initialize_copy(obj)
	@mat, @kind, @star, @main, @sub = obj.mat.dup, obj.kind, obj.star, obj.main, obj.sub
end

#inspect(fmt = ->(r){"Rational(#{r.numerator}, #{r.denominator})"}) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/mgmg/poly.rb', line 73

def inspect(fmt=->(r){"Rational(#{r.numerator}, #{r.denominator})"})
	foo = []
	(@mat.col_size-1).downto(0) do |c|
		bar = []
		(@mat.row_size-1).downto(0) do |s|
			value = @mat.body[s][c]
			bar << str(value, fmt)
		end
		buff = bar[0]
		buff = "#{buff}*s+#{bar[1]}" if 1 < bar.length
		2.upto(bar.length-1) do |i|
			buff = "(#{buff})*s+#{bar[i]}"
		end
		foo << buff
	end
	ret = foo[0]
	1.upto(foo.length-1) do |i|
		ret = "(#{ret})*c+#{foo[i]}"
	end
	ret
end

#leading(fmt = nil) ⇒ Object



94
95
96
97
98
99
100
101
# File 'lib/mgmg/poly.rb', line 94

def leading(fmt=nil)
	value = self[-1, -1]
	if fmt.nil?
		value
	else
		str(value, fmt)
	end
end

#partial_derivative(variable) ⇒ Object



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# File 'lib/mgmg/poly.rb', line 165

def partial_derivative(variable)
	case variable.to_s
	when /\Ac/i
		if @mat.col_size <= 1
			self.class.new(Mat.new(1, 1, 0), 28, 0, 12, 12)
		else
			mat = Mat.new(@mat.row_size, @mat.col_size-1) do |i, j|
				@mat.body[i][j+1] * (j+1)
			end
			self.class.new(mat, 28, 0, 12, 12)
		end
	when /\As/i
		if @mat.row_size <= 1
			self.class.new(Mat.new(1, 1, 0), 28, 0, 12, 12)
		else
			mat = Mat.new(@mat.row_size-1, @mat.col_size) do |i, j|
				@mat.body[i+1][j] * (i+1)
			end
			self.class.new(mat, 28, 0, 12, 12)
		end
	else
		raise ArgumentError, "the argument must be `s' or `c', not `#{variable}'"
	end
end

#quo(val) ⇒ Object Also known as: /



158
159
160
161
162
# File 'lib/mgmg/poly.rb', line 158

def quo(val)
	ret = self.dup
	ret.mat.scalar!(1.quo(val))
	ret
end

#scalar(val) ⇒ Object Also known as: *



152
153
154
155
156
# File 'lib/mgmg/poly.rb', line 152

def scalar(val)
	ret = self.dup
	ret.mat.scalar!(val)
	ret
end

#smith_balance(other, order = -1)) ⇒ Object



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/mgmg/poly.rb', line 102

def smith_balance(other, order=-1)
	o_org = order
	order += @mat.col_size if order < 0
	if order < 0 || @mat.col_size <= order || other.mat.col_size <= order then
		raise ArgumentError, "given order #{o_org} is out of range [-max(#{@mat.col_size}, #{other.mat.col_size}), max(#{@mat.col_size}, #{other.mat.col_size})-1]"
	end
	a, b, c, d = @mat.body[1][order], @mat.body[0][order], other.mat.body[1][order], other.mat.body[0][order]
	if a == c
		return( b == d )
	else
		return( (d-b).quo(a-c).to_ii )
	end
end

#smith_eff(smith, comp = smith) ⇒ Object



189
190
191
# File 'lib/mgmg/poly.rb', line 189

def smith_eff(smith, comp=smith)
	partial_derivative('s').evaluate(smith, comp).quo(2*(smith-1))
end

#smith_fix(smith, fmt = nil) ⇒ Object



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/mgmg/poly.rb', line 115

def smith_fix(smith, fmt=nil)
	foo = []
	(@mat.col_size-1).downto(0) do |c|
		bar = 0
		(@mat.row_size-1).downto(0) do |s|
			bar += ( @mat.body[s][c] * (smith**s) )
		end
		bar = str(bar, fmt)
		case c
		when 0
			# nothing to do
		when 1
			bar << 'C'
		else
			bar << "C^#{c}"
		end
		foo << bar
	end
	foo.join('+')
end

#to_s(fmt = nil) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/mgmg/poly.rb', line 17

def to_s(fmt=nil)
	foo = []
	(@mat.col_size-1).downto(0) do |c|
		bar = []
		(@mat.row_size-1).downto(0) do |s|
			value = @mat.body[s][c]
			baz = str(value, fmt)
			case s
			when 0
				# nothing to do
			when 1
				baz << 'S'
			else
				baz << "S^#{s}"
			end
			bar << baz if value != 0
		end
		case bar.length
		when 0
			next
		when 1
			bar = bar[0]
		else
			bar = "(#{bar.join('+')})"
		end
		case c
		when 0
			# nothing to do
		when 1
			bar << 'C'
		else
			bar << "C^#{c}"
		end
		foo << bar
	end
	foo.join('+').tap{|r| break str(0.quo(1), fmt) if r==''}
end