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.

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

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

#<(other) ⇒ Object

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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: /

[View source]

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: *

[View source]

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

[View source]

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

[View source]

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

[View source]

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

[View source]

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