Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[Functions:
- NOTE:I designed this script pretty much not to syntax error at all, so your answers will appear calculated even
- if you make a mistake.
- On all of these that include second arguments, the second argument is optional.
- i.add (Complex_Number[, Complex Number])-- Add two complex numbers
- i.subtract (Complex_Number[, Complex Number])-- Subtract two complex numbers (Distributive property)
- i.multiply(Complex_Number[, Complex Number]) -- Multiply two complex numbers
- i.divide(Complex_Number[, Complex Number]) -- Divide two complex numbers
- i.simplify(Complex_Number) -- Simplify one complex equation
- You cannot multiply inside parentheses in i.simplify, just add and subtract. BAD: (4*3i) GOOD: (4)*(3i)
- Alright, with i.simlpify you can use parentheses; however, you cannot place them inside each other BAD:(3+(4i)).
- Also, seldom use simplify as it is much slower than the other functions (even divide).
- Doing 100,000 calculations of the same equation, i.simplify was 6 seconds slower than i.divide.
- In the future I might add exponentiation. Currently, if I do, it will be limited to complex
- numbers to real powers or real numbers to complex powers (not complex to complex). Unfortunately, my brief brush
- with imaginary numbers in math class didn't teach me how to exponentiate complex numbers (if I do, n will be 0
- if you understand), and I don't know calculus.]]
- _G.i={
- add=function(a,b)
- b=b or "0" -- Additive identity
- local aValues, bValues, computedValues={},{},{} -- The values in a and b, and the final values
- local numPattern="[%+%-]?%d+%.?%d*i?" -- The pattern of a number
- setmetatable(aValues, {__add=function(Table1,Table2) -- Yay! Addition.
- function copy(Table) blarg={} for i,v in pairs(Table) do blarg[i]=v end return blarg end
- table1=copy(Table1) -- I don't want to edit the table
- table2=copy(Table2) -- Same
- local realLikeTerms={} -- The real like terms
- local imaginaryLikeTerms={} -- The imaginary like terms
- for i, v in pairs(table1) do -- Seperate the real from the imaginary in string a
- if v:find("i") then
- table.insert(imaginaryLikeTerms, v)
- else
- table.insert(realLikeTerms, v)
- end
- end
- for i, v in pairs(table2) do -- Seperate the real from the imaginary in string b
- if v:find("i") then
- table.insert(imaginaryLikeTerms, v)
- else
- table.insert(realLikeTerms, v)
- end
- end
- RealPart=0 -- The real value of the real number
- ImaginaryPart=0 -- The real value of the imaginary number (4i=4)
- for i,v in pairs(realLikeTerms) do -- Combine real like terms
- RealPart=RealPart+tonumber(v)
- end
- for i,v in pairs(imaginaryLikeTerms) do -- Combine imaginary like terms
- ImaginaryPart=ImaginaryPart+tonumber(v:sub(1,#v-1))
- end
- if ImaginaryPart==0 then -- Make it look pretty
- return tostring(RealPart)
- elseif ImaginaryPart < 0 then
- return tostring(RealPart)..tostring(ImaginaryPart).."i"
- else
- return tostring(RealPart).."+"..tostring(ImaginaryPart).."i"
- end
- end
- })
- for x in string.gmatch(a, numPattern) do -- Find all the numbers in a
- table.insert(aValues, x)
- end
- for x in string.gmatch(b, numPattern) do -- Find all the numbers in b
- table.insert(bValues, x)
- end
- function Equal(Table1, Table2) -- Make the tables equal length
- if #Table1 > #Table2 then
- for i=1,#Table1-#Table2 do
- table.insert(Table2, "+0")
- end
- elseif #Table1 < #Table2 then
- for i=1,#Table2-#Table1 do
- table.insert(Table1, "+0")
- end
- else
- end
- end
- Equal(aValues,bValues) -- Call equal
- computedValues=aValues+bValues -- Get the actual valus
- return computedValues
- end,
- subtract=function(a,b)
- b=b or "0" -- Additive identity
- local aValues, bValues, computedValues={},{},{} -- The values in a, the values in b, the final values
- local numPattern="[%+%-]?%d+%.?%d*i?" -- The number pattern
- setmetatable(aValues, {__sub=function(Table1,Table2) -- Yay! Subtraction.
- function copy(Table) blarg={} for i,v in pairs(Table) do blarg[i]=v end return blarg end
- table1=copy(Table1) -- I don't want to edit the table
- table2=copy(Table2) -- Same
- local realLikeTerms={} -- The real like terms
- local imaginaryLikeTerms={} -- The imaginary like terms
- for i, v in pairs(table1) do -- Sort fact from fiction in a
- if v:find("i") then
- table.insert(imaginaryLikeTerms, v)
- else
- table.insert(realLikeTerms, v)
- end
- end
- for i, v in pairs(table2) do -- in b
- if v:find("i") then
- table.insert(imaginaryLikeTerms, v)
- else
- table.insert(realLikeTerms, v)
- end
- end
- RealPart=0
- ImaginaryPart=0
- for i,v in pairs(realLikeTerms) do -- Combine real like terms
- RealPart=RealPart+tonumber(v)
- end
- for i,v in pairs(imaginaryLikeTerms) do -- Combine imaginary like terms
- ImaginaryPart=ImaginaryPart+tonumber(v:sub(1,#v-1)) -- Plus because of distributive property.
- end
- if ImaginaryPart == 0 then -- Make it look pretty
- return tostring(RealPart)
- elseif ImaginaryPart < 0 then
- return tostring(RealPart)..tostring(ImaginaryPart).."i"
- else
- return tostring(RealPart).."+"..tostring(ImaginaryPart).."i"
- end
- end
- })
- for x in string.gmatch(a, numPattern) do -- Get all the numbers in a
- table.insert(aValues, x)
- end
- for x in string.gmatch(b, numPattern) do -- Get all the numbers in b
- table.insert(bValues, x)
- end
- function Equal(Table1, Table2) -- Make the tables equal length for easier computations
- if #Table1 > #Table2 then
- for i=1,#Table1-#Table2 do
- table.insert(Table2, "+0")
- end
- elseif #Table1 < #Table2 then
- for i=1,#Table2-#Table1 do
- table.insert(Table1, "+0")
- end
- else
- end
- end
- Equal(aValues,bValues) -- Make the tables equal length
- setmetatable(bValues, {__unm=function(s) -- Distribute the negative sign
- blarg={}
- for i,v in pairs(s) do
- r=tonumber(v:match("[%+%-]?%d+%.?%d*")) -- Get the actual numbers
- r=-r
- if v:find("i") then -- Add them to the right thing
- blarg[i]=tostring(r).."i"
- else
- blarg[i]=tostring(r)
- end
- end
- return blarg
- end
- })
- bValues=-bValues -- Apply the negative sign
- computedValues=aValues-bValues -- Compute the values
- return computedValues
- end,
- multiply=function(a,b)
- b=b or "1" -- Multiplicative identity
- local aReal, aImaginary, bReal, bImaginary, computedValues, aValues, bValues={},{},{},{},{},{},{} -- Real in a and b, imaginary in a and b, all in a and b, and the final values
- local numPattern="[%+%-]?%d+%.?%d*i?"
- setmetatable(aValues, {__mul=function(Table1,Table2) -- Yay! Multiplication.
- function copy(Table) blarg={} for i,v in pairs(Table) do blarg[i]=v end return blarg end
- table1=copy(Table1) -- I don't want to edit the tables
- table2=copy(Table2)
- for i, v in pairs(table1) do -- Sort real from imaginary
- if v:find("i") then
- table.insert(aImaginary, v)
- else
- table.insert(aReal, v)
- end
- end
- for i, v in pairs(table2) do -- Same
- if v:find("i") then
- table.insert(bImaginary, v)
- else
- table.insert(bReal, v)
- end
- end
- RealPart=0 -- Absolute real value
- ImaginaryPart=0 -- Absolute imaginary value
- for i,v in pairs(aReal) do -- Multiply all the real values in a
- for x,y in pairs(bReal) do -- and all the real in b
- RealPart=RealPart+(v*y)
- end
- end
- for i,v in pairs(aReal) do -- Multiply all the real values of a
- for x,y in pairs(bImaginary) do -- by the imaginary of b
- z=y:sub(1,#y-1)
- ImaginaryPart=ImaginaryPart+(v*z)
- end
- end
- for i,v in pairs(aImaginary) do -- Multiply all the imaginary values of a
- for x,y in pairs(bReal) do -- by the real of b
- z=v:sub(1,#v-1) -- Cut off the i!
- ImaginaryPart=ImaginaryPart+(z*y)
- end
- end
- for i,v in pairs(aImaginary) do -- Multiply all the imaginary values of a
- for x,y in pairs(bImaginary) do -- By the imaginary of b
- a=v:sub(1,#v-1) -- Cut off the i!
- b=y:sub(1,#y-1) -- Cut off the i!
- RealPart=RealPart-(a*b) -- Subtract, because i*i=i^2=-1
- end
- end
- if ImaginaryPart==0 then -- Make it look pretty
- return tostring(RealPart)
- elseif ImaginaryPart < 0 then
- return tostring(RealPart)..tostring(ImaginaryPart).."i"
- else
- return tostring(RealPart).."+"..tostring(ImaginaryPart).."i"
- end
- end
- })
- for x in string.gmatch(a, numPattern) do -- Get the numbers in a
- table.insert(aValues, x)
- end
- for x in string.gmatch(b, numPattern) do -- and b
- table.insert(bValues, x)
- end
- function Equal(Table1, Table2) -- Make the lengths equal
- if #Table1 > #Table2 then
- for i=1,#Table1-#Table2 do
- table.insert(Table2, "+0")
- end
- elseif #Table1 < #Table2 then
- for i=1,#Table2-#Table1 do
- table.insert(Table1, "+0")
- end
- else
- end
- end
- Equal(aValues,bValues)
- computedValues=aValues*bValues
- return computedValues
- end,
- divide=function(a,b)
- b=b or "1" -- Multiplicative identity
- local aReal, aImaginary, bReal, bImaginary, computedValues, aValues, bValues={},{},{},{},{},{},{} -- Real in a and b, imaginary in a and b, all in a and b, and final.
- local numPattern="[%+%-]?%d+%.?%d*i?"
- setmetatable(aValues, {__div=function(Table1,Table2) -- Yay! Division.
- function copy(Table) blarg={} for i,v in pairs(Table) do blarg[i]=v end return blarg end
- table1=copy(Table1) -- I don't want to edit the originals
- table2=copy(Table2)
- for i, v in pairs(table1) do -- Seperate i values from r values
- if v:find("i") then
- table.insert(aImaginary, v)
- else
- table.insert(aReal, v)
- end
- end
- for i, v in pairs(table2) do -- Same
- if v:find("i") then
- table.insert(bImaginary, v)
- else
- table.insert(bReal, v)
- end
- end
- NumRealPart=0 -- The real part of the numerator
- NumImaginaryPart=0 -- The imaginary part of the numerator
- DenRealPart=0 -- The real part of the denominator
- DenImaginaryPart=0 -- The imaginary part of the denominator
- for i,v in pairs(aReal) do
- NumRealPart=NumRealPart+v -- Combine real like terms for the numerator
- end
- for i,v in pairs(bReal) do
- DenRealPart=DenRealPart+v -- Combine real like terms for the denominator
- end
- for i,v in pairs(aImaginary) do
- r=v:sub(1,#v-1) -- Cut off the i!
- NumImaginaryPart=NumImaginaryPart+r -- Combine imaginary like terms for the numerator
- end
- for i,v in pairs(bImaginary) do
- r=v:sub(1,#v-1) -- Cut off the i!
- DenImaginaryPart=DenImaginaryPart+r -- Combine imaginary like terms for the denominator
- end
- Conjugate=tostring(DenRealPart).."+"..tostring(-DenImaginaryPart).."i" -- The complex conjugate, required to remove square roots from the denominator
- Denominator=_G.i.multiply(tostring(DenRealPart).."+"..tostring(DenImaginaryPart).."i", Conjugate) -- Multiply both top
- Numerator=_G.i.multiply(tostring(NumRealPart).."+"..tostring(NumImaginaryPart).."i", Conjugate) -- and bottom by conjugate
- NumReal=tonumber(Numerator:match("[%+%-]?%d+%.?%d*")) -- The real part of the numerator
- Start,Finish=Numerator:find("[%+%-]?%d+%.?%d*") -- Find out where it ends
- NumImaginary=tonumber(Numerator:match("[%+%-]?%d+%.?%d*", Finish+1)) -- So we can get the real part of the imaginary number of the denominator
- DenReal=tonumber(Denominator:match("[%+%-]?%d+%.?%d*")) -- Get the real (only) part of the denominator
- NumReal=NumReal/DenReal -- Divide the real part of numerator by the real part of the denominator
- NumImaginary=NumImaginary or 0 -- So the script doesn't error
- NumImaginary=NumImaginary/DenReal -- Divide the real part of the imaginary by the real (only) part of the denominator
- if NumImaginary==0 then -- Make it look pretty
- return tostring(NumReal)
- elseif NumImaginary<0 then
- return tostring(NumReal)..tostring(NumImaginary).."i"
- else
- return tostring(NumReal).."+"..tostring(NumImaginary).."i"
- end
- end
- })
- for x in string.gmatch(a, numPattern) do -- Get all the values in a
- table.insert(aValues, x)
- end
- for x in string.gmatch(b, numPattern) do -- and b.
- table.insert(bValues, x)
- end
- computedValues=aValues/bValues -- Combine!
- return computedValues
- end,
- simplify=function (a)
- local numPattern="[%+%-%*%/]?[%+%-]?%d+%.?%d*i?" -- The number pattern and it's operator(s).
- gfind=function(String, Pattern1, Pattern2) -- So I can find the proper values
- local start=1 -- Where to start
- Pattern2=Pattern2 or Pattern1 -- Pattern2 is optional, so it might have to be pattern 1
- return function() -- Because of the 'g' in gfind. ROBLOX wouldn't let me edit the string library.
- x,y=String:find(Pattern1, start) -- Search for pattern 1
- w,z=String:find(Pattern2, start) -- Search for pattern 2
- if x and w and x >= w then -- Both there, see if Pattern1 is after Pattern2
- start=z+1 -- Start searching after
- return w, z, String:sub(w,z)
- elseif x and w and x < w then -- Both there, see if Pattern1 is before Pattern2
- start=y+1 -- Start searching after
- return x, y, String:sub(x,y)
- elseif x and not w then -- If only Pattern1 is there
- start=y+1
- return x, y, String:sub(x,y)
- elseif w and not x then -- If only Pattern2 is there
- start=z+1
- return w, z, String:sub(w,z)
- end
- end
- end
- local Imaginaries={} -- The complex numbers
- for start, finish, value in gfind(a, "[%+%-%*%/]?[%+%-]?%(.-%)", numPattern) do -- To find all the numbers I need, whether in parentheses or not.
- table.insert(Imaginaries, value)
- end
- local function Rarg(Table)
- for j,v in pairs(Table) do
- if v:find("%-%(") then -- Does it have a negative in need of distribution?
- local x,y=v:find("%-%(") -- Find it.
- v=v:sub(1,x-1)..i.subtract("0", v) -- Subtract it from 0 to make it negative!
- end
- if v:find("%*") then -- If I should multiply it
- Table[j-1]=_G.i.multiply(v, Table[j-1]) -- Move it to right before
- table.remove(Table, j) -- Remove where it would have been
- Rarg(Table) -- Call it again, with the new table.
- elseif v:find("%/") then -- Find if division
- if not Table[j-1]:find("%*") then -- Make sure there isn't multiplication I need to do
- Table[j-1]=_G.i.divide(Table[j-1], v) -- Divide!
- table.remove(Table, j) -- Remove pointless space
- Table[j-1]="+"..Table[j-1] -- Make sure there's an operator there!
- Rarg(Table) -- Call again
- end
- end
- end
- return Table -- Return the finished off thingy
- end
- Imaginaries=Rarg(Imaginaries) -- Simplify
- a=a or "0"
- return _G.i.add(table.concat(Imaginaries,"+")) -- Simplify the version with a +, that does no harm to my add script.
- end
- }
Advertisement
Add Comment
Please, Sign In to add comment