Editing
Module:FunctionGraph
Jump to navigation
Jump to search
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local p = {} local comp_number = nil local getArgs = require('Module:Arguments').getArgs local lib_calc = require('Module:Complex_Number/Calculate') local TrackingCategory = require('Module:TrackingCategory') local noop_func = function()end function p.applyFunctionGraph(frame) local working_frame = mw.getCurrentFrame() local body = working_frame:extensionTag{ name = 'graph', content = require('Module:FunctionGraph/Graph').chart(frame) } return body end function p.functionGraph(frame) if comp_number == nil then comp_number = require("Module:Complex Number") end local cmath, qmath = comp_number.cmath.init(), comp_number.qmath.init() if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {parentFirst=true}) local exprs = {} local body_args, x_start, x_end, y_min, y_max, sampling = {}, 0, 1, nil, nil, 50 for arg_name, arg_value in pairs( args ) do local check_arg_name = mw.ustring.lower(tostring(arg_name)) if tonumber(arg_name) ~= nil then exprs[#exprs + 1] = lib_calc._remove_strip_marker(arg_value) elseif check_arg_name == "start" then x_start = tonumber(arg_value) elseif check_arg_name == "end" then x_end = tonumber(arg_value) elseif check_arg_name == "sampling" then sampling = tonumber(arg_value) elseif check_arg_name == "min" then y_min = tonumber(arg_value) elseif check_arg_name == "max" then y_max = tonumber(arg_value) else body_args[arg_name] = arg_value end end local yesno = require('Module:Yesno') if yesno(args.useOtherModule or 'no') == true then lib_calc.use_other_module = true end local math_class = frame.args['class']or'' local mymath = cmath local mytomath = cmath.toComplexNumber if mw.ustring.sub(math_class,1,7):upper()=="MODULE:" then local module_name, math_lib_name = lib_calc.checkModuleClass(math_class) xpcall(function() local load_module = require("Module:"..module_name) if load_module ~= nil then local load_math_lib = load_module[math_lib_name] if load_module ~= nil then local func_type = type(noop_func) local my_math_lib = (type(load_math_lib.init) == func_type) and load_math_lib.init() or load_math_lib if type(my_math_lib.constructor) == func_type then math_class = "mymath" mymath = my_math_lib mytomath = my_math_lib.constructor end end end end,noop_func) end local body = p._functionGraph(exprs, x_start, x_end, sampling, y_min, y_max, body_args, ( { cmath = cmath, qmath = qmath, mymath = mymath, } ) [math_class] , (( { cmath = cmath.toComplexNumber, qmath = qmath.toQuaternionNumber, mymath = mytomath, } ) [math_class] ) ) body.width = 400 body.height = 100; body.type="line" body.interpolate = frame.args['interpolate'] or "monotone" for arg_name, arg_value in pairs( body_args ) do body[arg_name] = arg_value end --body = mw.getCurrentFrame():expandTemplate{title = "Graph:Chart", args = body} body = p.applyFunctionGraph(body) if use_ext_mathlib == true then TrackingCategory.append('使用擴充複變函數庫的頁面') end return body end function p.calc_table(frame) local variable_process = require("Module:Number/data") local args local can_math = false local should_math = false local show_math = false if frame == mw.getCurrentFrame() then -- We're being called via #invoke. The args are passed through to the module -- from the template page, so use the args that were passed into the template. args = getArgs(frame, { parentFirst=true, trim = false, removeBlanks = false }) --frame.args local yesno = require('Module:Yesno') can_math = yesno(args['use math'] or args['use_math']) should_math = yesno(args['should math'] or args['should_math']) else -- We're being called from another module or from the debug console, so assume -- the args are passed in directly. args = frame end lib_calc._randomseed() local yesno = require('Module:Yesno') if yesno(args.useOtherModule or 'no') == true then lib_calc.use_other_module = true end local first_number_list = {"2","3","4","5","6","7","8","9"} local second_number_list, first_number_show, second_number_show local calculate_str, calculate_title = "{{{left}}} * {{{right}}}", "×" if args['number list'] or args['number_list'] then first_number_list = mw.text.split(args['number list'] or args['number_list'] or '',',') end if args['number list2'] or args['number_list2'] then second_number_list = mw.text.split(args['number list2'] or args['number_list2'] or '',',') end if args['number list show'] or args['number_list_show'] then first_number_show = mw.text.split(args['number list show'] or args['number_list_show'] or '',',') if #first_number_show == 1 and mw.text.trim(first_number_show[1]) == '' then first_number_show = {} end end if args['number list show2'] or args['number_list_show2'] then second_number_show = mw.text.split(args['number list show2'] or args['number_list_show2'] or '',',') if #second_number_show == 1 and mw.text.trim(second_number_show[1]) == '' then second_number_show = {} end end if args['calculate'] then calculate_str = mw.text.trim(lib_calc._remove_strip_marker(args['calculate'])) end if args['calculate title'] or args['calculate_title'] then calculate_title = mw.text.trim(args['calculate title'] or args['calculate_title']) end if second_number_list == nil or (second_number_list and (second_number_list == {} or #second_number_list == 0) ) then second_number_list = first_number_list end if first_number_show == nil or (first_number_show and (first_number_show == {} or #first_number_show == 0) ) then first_number_show = first_number_list end if second_number_show == nil or (second_number_show and (second_number_show == {} or #second_number_show == 0) ) then second_number_show = first_number_show end local body, buffer_str, table_str = "", '', '' if comp_number == nil then comp_number = require("Module:Complex Number") end local cmath, qmath, bmath = comp_number.cmath.init(), comp_number.qmath.init(), comp_number.bmath.init() local mathtag = lib_calc.tagmath.init() local math_class = args['class']or'' if mw.text.trim(math_class) == '' then math_class = "cmath" end local mymath = cmath local mytomath = cmath.toComplexNumber if mw.ustring.sub(math_class,1,7):upper()=="MODULE:" then local module_name, math_lib_name = lib_calc.checkModuleClass(math_class) xpcall(function() local load_module = require("Module:"..module_name) if load_module ~= nil then local load_math_lib = load_module[math_lib_name] if load_module ~= nil then local func_type = type(noop_func) local my_math_lib = (type(load_math_lib.init) == func_type) and load_math_lib.init() or load_math_lib if type(my_math_lib.constructor) == func_type then math_class = "mymath" mymath = my_math_lib mytomath = my_math_lib.constructor end end end end,noop_func) end body = body .. "! " .. (args["main head css"] or args["main_head_css"] or '') .. " | " .. calculate_title .. ' \n' for j=1,#second_number_list do local second_it = mw.text.trim(second_number_list[j] or '') local second_it_show = mw.text.trim(second_number_show[j] or '') if second_it ~= nil then local second_num_math = tostring(second_it_show or second_it) if should_math or can_math then if args.class ~= "mathtag" and yesno(args['show math'] or args['show_math']) then second_num_math = lib_calc._re_math_output(second_num_math) end second_num_math = lib_calc._adj_math_output(second_num_math) end if can_math then second_num_math = frame:callParserFunction{name = "#tag:math", args = {second_num_math}} end body = body .. "! " .. (args["head css"] or args["head_css"] or '') .. " | " .. second_num_math .. ' \n' end end body = body .. '\n' for i=1,#first_number_list do local first_it = mw.text.trim(first_number_list[i] or '') local first_it_show = mw.text.trim(first_number_show[i] or '') if first_it ~= nil then body = body .. "|-\n"; table_str = '' local first_num_math = tostring(first_it_show or first_it) if should_math or can_math then if args.class ~= "mathtag" and yesno(args['show math'] or args['show_math']) then first_num_math = lib_calc._re_math_output(first_num_math) end first_num_math = lib_calc._adj_math_output(first_num_math) end if can_math then first_num_math = frame:callParserFunction{name = "#tag:math", args = {first_num_math}} end body = body .. "! " .. (args["head css"] or args["head_css"] or '') .. " | " .. first_num_math .. " \n" for j=1,#second_number_list do local second_it = mw.text.trim(second_number_list[j] or '') if second_it ~= nil then buffer_str = variable_process._getFormatingStringByArgument(calculate_str, { left=tostring(first_it),right=tostring(second_it) }) local exec_result = lib_calc.calc( buffer_str or '', ( { cmath = cmath, qmath = qmath, bmath = bmath, mathtag = mathtag, mymath = mymath } ) [ math_class ] , (( { cmath = cmath.toComplexNumber, qmath = qmath.toQuaternionNumber, bmath = bmath.toBoolean, mathtag = mathtag.toTagMath, mymath = mytomath } ) [ math_class ] ) ) local exec_result_str = mw.text.trim(tostring(exec_result) or '') local exec_check = mw.text.trim((tonumber(exec_result_str) and args[tonumber(exec_result_str)]) or args[exec_result_str] or '') if exec_check == '' then exec_check = nil end table_str = table_str .. '|' .. (exec_check or args["number css"] or args["number_css"] or '') .. "| " if should_math or can_math then if args.class ~= "mathtag" and yesno(args['show math'] or args['show_math']) then exec_result_str = lib_calc._re_math_output(exec_result_str) end exec_result_str = lib_calc._adj_math_output(exec_result_str) end if can_math then exec_result_str = frame:callParserFunction{name = "#tag:math", args = {exec_result_str}} end table_str = table_str .. mw.text.trim(exec_result_str) .. ' \n' end end body = body .. table_str end end if use_ext_mathlib == true then TrackingCategory.append('使用擴充複變函數庫的頁面') end return body end function p._functionGraph(expr_arr,x_start,x_end,sampling, y_min, y_max, body_args, math_lib, number_Constructer) if (yesno or require('Module:Yesno'))((body_args or {}).useOtherModule or 'no') == true then lib_calc.use_other_module = true end if comp_number == nil then comp_number = require("Module:Complex Number") end math = comp_number.math.init() lib_calc._randomseed() local mathlib, numberConstructer = math_lib or math, number_Constructer or tonumber local postfix = {} local check_func = {} local x_arr, y_arr = {}, {} if type(expr_arr) == type({}) then for i=1,#expr_arr do local local_func_sign = '↦' local check_parametric = mw.text.split(expr_arr[i],';') --解決 函數-參數式 衝突 if mw.ustring.find(expr_arr[i], local_func_sign) then check_parametric = mw.text.split(expr_arr[i],'\\;')end if #check_parametric == 1 then local pre_expr, pre_scope = lib_calc._function_preprocessing(expr_arr[i], mathlib, numberConstructer, false) postfix[#postfix + 1] = lib_calc.infixToPostfix(pre_expr, debug_flag) if pre_scope then postfix[#postfix].scope = pre_scope end elseif #check_parametric >= 3 then postfix[#postfix + 1]={parametric=true} postfix[#postfix].x_name = check_parametric[1] or 't' postfix[#postfix].y_name = check_parametric[2] or 't' postfix[#postfix].x = lib_calc.infixToPostfix(check_parametric[1] or 't', debug_flag) postfix[#postfix].y = lib_calc.infixToPostfix(check_parametric[2] or 't', debug_flag) postfix[#postfix].t = mw.text.trim(check_parametric[3] or 't') postfix[#postfix].min = numberConstructer(check_parametric[4]) or numberConstructer(0) postfix[#postfix].max = numberConstructer(check_parametric[5]) or numberConstructer(1) end y_arr[#y_arr + 1] = {} x_arr[#x_arr + 1] = {} end else local local_func_sign = '↦' local check_parametric = mw.text.split(expr_arr,';') --解決 函數-參數式 衝突 if mw.ustring.find(expr_arr, local_func_sign) then check_parametric = mw.text.split(expr_arr,'\\;')end if #check_parametric == 1 then local pre_expr, pre_scope = lib_calc._function_preprocessing(expr_arr, mathlib, numberConstructer, false) postfix[#postfix + 1] = lib_calc.infixToPostfix(pre_expr, debug_flag) if pre_scope then postfix[#postfix].scope = pre_scope end elseif #check_parametric >= 3 then postfix[#postfix + 1]={parametric=true} postfix[#postfix].x_name = check_parametric[1] or 't' postfix[#postfix].y_name = check_parametric[2] or 't' postfix[#postfix].x = lib_calc.infixToPostfix(check_parametric[1] or 't', debug_flag) postfix[#postfix].y = lib_calc.infixToPostfix(check_parametric[2] or 't', debug_flag) postfix[#postfix].t = check_parametric[3] or 't' postfix[#postfix].min = numberConstructer(check_parametric[4]) or numberConstructer(0) postfix[#postfix].max = numberConstructer(check_parametric[5]) or numberConstructer(1) end y_arr[#y_arr + 1] = {} x_arr[#x_arr + 1] = {} end local check_cexpr = mw.title.new("cexpr","template"):getContent() local check_isreal = mw.title.new("isReal","template"):getContent() local check_ifNumeric = mw.title.new("ifNumeric","template"):getContent() for i=0,sampling do local it = x_start + (i * (x_end-x_start) / sampling) local x_val = it for j=1,#expr_arr do local calc_val = " " xpcall(function() if type(postfix[j]) == type({}) and postfix[j].parametric == true then local it_t = postfix[j].min + (i * (postfix[j].max - postfix[j].min) / sampling) --參數式 calc_val = lib_calc.calc_by_postfix(postfix[j].y, {[postfix[j].t]=it_t}, mathlib, numberConstructer, false) x_val = lib_calc.calc_by_postfix(postfix[j].x, {[postfix[j].t]=it_t}, mathlib, numberConstructer, false) else calc_val = lib_calc.calc_by_postfix(postfix[j], { x=it, last=function(num) --for Template:數列 local last_num = (body_args or {})['last' .. tonumber(tostring(num or 1))] or 0 return numberConstructer(y_arr[j][#(y_arr[j])-(tonumber(tostring(num))or 1)+1] or last_num) end, }, mathlib, numberConstructer, false) if( tonumber((body_args or {})["calc diff " .. tostring(j) ]) == 1 or ((yesno or require('Module:Yesno'))((body_args or {})["calc diff " .. tostring(j) ]or'no')==true) )then local dy = lib_calc.calc_by_postfix(postfix[j], {x=(it + 1e-6)}, mathlib, numberConstructer, false) calc_val = 1e6 * (dy - calc_val) end end if y_max and mathlib.re(calc_val) > y_max then calc_val = y_max end if y_min and mathlib.re(calc_val) < y_min then calc_val = y_min end if x_end and mathlib.re(x_val) > x_end then x_val = x_end end if x_start and mathlib.re(x_val) < x_start then x_val = x_start end end,function(_)end) if tonumber((body_args or {})["round number"]) ~= nil then if calc_val then calc_val = mathlib.round(calc_val, tonumber((body_args or {})["round number"]), 10) end end if tonumber((body_args or {})["nonreal is nan"]) == 1 then if math.abs(tonumber(mathlib.abs(mathlib.nonRealPart(calc_val))) or 0) > 1e-14 then calc_val = nil end end local num_check = mw.ustring.lower(tostring(numberConstructer(calc_val))) if mw.ustring.match(num_check,"nan") or mw.ustring.match(num_check,"nil") or mw.ustring.match(num_check,"inf") then calc_val = ' ' end num_check = mw.ustring.lower(tostring(numberConstructer(x_val))) if mw.ustring.match(num_check,"nan") or mw.ustring.match(num_check,"nil") or mw.ustring.match(num_check,"inf") then x_val = ' ' end y_arr[j][ (#(y_arr[j]) + 1) ] = tostring(calc_val) x_arr[j][ (#(x_arr[j]) + 1) ] = tostring(x_val) end end local result={} if #expr_arr > 0 then result.legend = "函數" end for i=1,#expr_arr do result['x'] = table.concat(x_arr[i],',') result['y' .. tostring(i)] = table.concat(y_arr[i],',') result['y' .. tostring(i) .. "Title"] = tostring( (body_args or {})[tostring(i) .. " name" ] or expr_arr[i] ) if type(postfix[i]) == type({}) and postfix[i].parametric == true then result['y' .. tostring(i) .. "Title"] = "x=" .. postfix[i].x_name .. "; y=" .. postfix[i].y_name elseif( tonumber((body_args or {})["calc diff " .. tostring(i) ]) == 1 )then result['y' .. tostring(i) .. "Title"] = '( ' .. result['y' .. tostring(i) .. "Title"] .. " )\'" end if check_func[ result['y' .. tostring(i) .. "Title"] ] ~= nil then local new_name = result['y' .. tostring(i) .. "Title"] .. " ,(" .. tostring(check_func[ result['y' .. tostring(i) .. "Title"] ]+1) .. ")" check_func[ result['y' .. tostring(i) .. "Title"] ] = check_func[ result['y' .. tostring(i) .. "Title"] ] + 1 result['y' .. tostring(i) .. "Title"] = new_name else check_func[ result['y' .. tostring(i) .. "Title"] ] = 1 end end return result end function p.complex_graph(frame) if comp_number == nil then comp_number = require("Module:Complex Number") end local cmath, qmath = comp_number.cmath.init(), comp_number.qmath.init() if not getArgs then getArgs = require('Module:Arguments').getArgs end local args = getArgs(frame, {parentFirst=true}) local expr = args[1] or args['1'] or 'x' local body_args, x_start, x_end, y_start, y_end, sampling, width = {}, -5, 5, -5, 5, 100, 120 for arg_name, arg_value in pairs( args ) do local check_arg_name = mw.ustring.gsub(mw.ustring.lower(tostring(arg_name)), "[ _]", "") if check_arg_name == "xstart" then x_start = tonumber(arg_value) elseif check_arg_name == "xend" then x_end = tonumber(arg_value) elseif check_arg_name == "ystart" then y_start = tonumber(arg_value) elseif check_arg_name == "yend" then y_end = tonumber(arg_value) elseif check_arg_name == "sampling" then sampling = tonumber(arg_value) elseif check_arg_name == "width" then width = tonumber(arg_value) else body_args[arg_name] = arg_value end end local yesno = require('Module:Yesno') if yesno(args.useOtherModule or 'no') == true then lib_calc.use_other_module = true end local math_class = frame.args['class']or'' local mymath = cmath local mytomath = cmath.toComplexNumber if mw.ustring.sub(math_class,1,7):upper()=="MODULE:" then local module_name, math_lib_name = lib_calc.checkModuleClass(math_class) xpcall(function() local load_module = require("Module:"..module_name) if load_module ~= nil then local load_math_lib = load_module[math_lib_name] if load_module ~= nil then local func_type = type(noop_func) local my_math_lib = (type(load_math_lib.init) == func_type) and load_math_lib.init() or load_math_lib if type(my_math_lib.constructor) == func_type then math_class = "mymath" mymath = my_math_lib mytomath = my_math_lib.constructor end end end end,noop_func) end local calc_result = p._complex_graph(expr, x_start, x_end, y_start, y_end, sampling ,width, body_args, ( { cmath = cmath, qmath = qmath, mymath = mymath, } ) [math_class] , (( { cmath = cmath.toComplexNumber, qmath = qmath.toQuaternionNumber, mymath = mytomath, } ) [math_class] ) ) local body = frame:callParserFunction{ name = '#tag:graph', args = { mw.text.jsonEncode(calc_result) } } if use_ext_mathlib == true then TrackingCategory.append('使用擴充複變函數庫的頁面') end return body end function p._complex_graph(expr, x_start, x_end, y_start, y_end, sampling, width, body_args, math_lib, number_Constructer) if (yesno or require('Module:Yesno'))((body_args or {}).useOtherModule or 'no') == true then lib_calc.use_other_module = true end if comp_number == nil then comp_number = require("Module:Complex Number") end local cmath = comp_number.cmath.init() lib_calc._randomseed() local mathlib, numberConstructer = math_lib or cmath, number_Constructer or cmath.constructor local pxsize = width local pre_expr, pre_scope = lib_calc._function_preprocessing(expr, mathlib, numberConstructer, false) local postfix = lib_calc.infixToPostfix(pre_expr, debug_flag) if pre_scope then postfix.scope = pre_scope end local function HSBToRGB(h, s, b) local function k(n) return (n + h / 60) % 6 end local function f(n) return b * (1 - s * math.max(0, math.min(k(n), 4 - k(n), 1))) end return 255 * f(5), 255 * f(3), 255 * f(1); end local result = {} local i_value = mathlib.elements and (mathlib.elements[2] and mathlib.elements[2] or mathlib.i) or mathlib.i if not i_value then error("繪製失敗:所用數體無非實數單位元") end for i=0,sampling do local it_y = y_start + (i * (y_end-y_start) / sampling) local calc_row = {} for j=0,sampling-1 do local it_x = x_start + (j * (x_end-x_start) / sampling) local it = mathlib[0] + it_x + i_value * it_y local calc_val = lib_calc.calc_by_postfix(postfix, {x=it}, mathlib, numberConstructer, false) local check_nan = not not(tostring(calc_val):match("[%+%-]?[Nn][IiAa][LlNn]")) local check_inf = not not(tostring(calc_val):match("[%+%-]?[Ii][Nn][Ff]")) local result_color = "rgb(127,127,127)" if not check_nan then if check_inf then result_color = "rgb(255,255,255)" else local h, s, b = (mathlib.re(mathlib.arg(calc_val)) / math.pi * 180) % 360, mathlib.re(mathlib.inverse(mathlib.log(mathlib.abs(calc_val) + 1) * 0.3 + 1)), mathlib.re(-mathlib.inverse(mathlib.log(mathlib.abs(calc_val) + 1) * 5 + 1.1) + 1) result_color = string.format("rgb(%d,%d,%d)", HSBToRGB(h + ((h < 0)and 360 or 0), s, b)) end end calc_row[#calc_row + 1] = result_color end result[#result + 1] = calc_row end local w_count = #result local cell_width = pxsize / (w_count+2) local graph_data = { width=pxsize, height=pxsize, data={}, padding={left=cell_width,top=cell_width,bottom=cell_width,right=cell_width}, scales={ {name="x",type="linear",domain={0,w_count},range="width"}, {name="y",type="linear",domain={0,w_count},range="height"}, }, marks={ { type="rect", from={data="funcdata"}, properties={ enter={ x={scale="x",field="0"},y={scale="y",field="1"}, width={value=cell_width},height={value=cell_width}, stroke={field="2"}, fill={field="2"}, } } } } } local func_data = {name="funcdata",values={}} for x=1,w_count do for y=1,#(result[x]) do func_data.values[#(func_data.values)+1] = {x-1,#(result[x])-y+1,result[y][x]} end end graph_data.data[#(graph_data.data)+1] = func_data return graph_data end return p
Summary:
Please note that all contributions to wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see
Wiki:Copyrights
for details).
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Navigation menu
Personal tools
Not logged in
Talk
Contributions
Create account
Log in
Namespaces
Page
Discussion
English
Views
Read
Edit
View history
More
Search
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Tools
What links here
Related changes
Special pages
Page information