merlin11188

Complex Numbers

Jul 1st, 2011
301
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 19.78 KB | None | 0 0
  1. --[[Functions:
  2. NOTE:I designed this script pretty much not to syntax error at all, so your answers will appear calculated even
  3. if you make a mistake.
  4.  
  5. On all of these that include second arguments, the second argument is optional.
  6. i.add (Complex_Number[, Complex Number])-- Add two complex numbers
  7. i.subtract (Complex_Number[, Complex Number])-- Subtract two complex numbers (Distributive property)
  8. i.multiply(Complex_Number[, Complex Number]) -- Multiply two complex numbers
  9. i.divide(Complex_Number[, Complex Number]) -- Divide two complex numbers
  10. i.simplify(Complex_Number) -- Simplify one complex equation
  11. You cannot multiply inside parentheses in i.simplify, just add and subtract. BAD: (4*3i) GOOD: (4)*(3i)
  12. Alright, with i.simlpify you can use parentheses; however, you cannot place them inside each other BAD:(3+(4i)).
  13. Also, seldom use simplify as it is much slower than the other functions (even divide).
  14. Doing 100,000 calculations of the same equation, i.simplify was 6 seconds slower than i.divide.
  15.  
  16. In the future I might add exponentiation. Currently, if I do, it will be limited to complex
  17. numbers to real powers or real numbers to complex powers (not complex to complex). Unfortunately, my brief brush
  18. with imaginary numbers in math class didn't teach me how to exponentiate complex numbers (if I do, n will be 0
  19. if you understand), and I don't know calculus.]]
  20. _G.i={
  21. add=function(a,b)
  22.         b=b or "0" -- Additive identity
  23.         local aValues, bValues, computedValues={},{},{} -- The values in a and b, and the final values
  24.         local numPattern="[%+%-]?%d+%.?%d*i?" -- The pattern of a number
  25.         setmetatable(aValues, {__add=function(Table1,Table2) -- Yay! Addition.
  26.                 function copy(Table) blarg={} for i,v in pairs(Table) do blarg[i]=v end return blarg end
  27.                 table1=copy(Table1) -- I don't want to edit the table
  28.                 table2=copy(Table2) -- Same
  29.                 local realLikeTerms={} -- The real like terms
  30.                 local imaginaryLikeTerms={} -- The imaginary like terms
  31.                 for i, v in pairs(table1) do -- Seperate the real from the imaginary in string a
  32.                         if v:find("i") then
  33.                                 table.insert(imaginaryLikeTerms, v)
  34.                                 else
  35.                                 table.insert(realLikeTerms, v)
  36.                         end
  37.                 end
  38.                 for i, v in pairs(table2) do -- Seperate the real from the imaginary in string b
  39.                         if v:find("i") then
  40.                                 table.insert(imaginaryLikeTerms, v)
  41.                                 else
  42.                                 table.insert(realLikeTerms, v)
  43.                         end
  44.                 end
  45.                 RealPart=0 -- The real value of the real number
  46.                 ImaginaryPart=0 -- The real value of the imaginary number (4i=4)
  47.                 for i,v in pairs(realLikeTerms) do -- Combine real like terms
  48.                         RealPart=RealPart+tonumber(v)
  49.                 end
  50.                 for i,v in pairs(imaginaryLikeTerms) do -- Combine imaginary like terms
  51.                         ImaginaryPart=ImaginaryPart+tonumber(v:sub(1,#v-1))
  52.                 end
  53.                 if ImaginaryPart==0 then -- Make it look pretty
  54.                         return tostring(RealPart)
  55.                         elseif ImaginaryPart < 0 then
  56.                         return tostring(RealPart)..tostring(ImaginaryPart).."i"
  57.                         else
  58.                         return tostring(RealPart).."+"..tostring(ImaginaryPart).."i"
  59.                 end
  60.         end
  61.         })
  62.         for x in string.gmatch(a, numPattern) do -- Find all the numbers in a
  63.                 table.insert(aValues, x)
  64.         end
  65.         for x in string.gmatch(b, numPattern) do -- Find all the numbers in b
  66.                 table.insert(bValues, x)
  67.         end
  68.         function Equal(Table1, Table2) -- Make the tables equal length
  69.                 if #Table1 > #Table2 then
  70.                         for i=1,#Table1-#Table2 do
  71.                                 table.insert(Table2, "+0")
  72.                         end
  73.                         elseif #Table1 < #Table2 then
  74.                         for i=1,#Table2-#Table1 do
  75.                                 table.insert(Table1, "+0")
  76.                         end
  77.                         else
  78.                 end
  79.         end
  80.         Equal(aValues,bValues) -- Call equal
  81.         computedValues=aValues+bValues -- Get the actual valus
  82.         return computedValues
  83. end,
  84. subtract=function(a,b)
  85.         b=b or "0" -- Additive identity
  86.         local aValues, bValues, computedValues={},{},{} -- The values in a, the values in b, the final values
  87.         local numPattern="[%+%-]?%d+%.?%d*i?" -- The number pattern
  88.         setmetatable(aValues, {__sub=function(Table1,Table2) -- Yay! Subtraction.
  89.                 function copy(Table) blarg={} for i,v in pairs(Table) do blarg[i]=v end return blarg end
  90.                 table1=copy(Table1) --  I don't want to edit the table
  91.                 table2=copy(Table2) -- Same
  92.                 local realLikeTerms={} -- The real like terms
  93.                 local imaginaryLikeTerms={} -- The imaginary like terms
  94.                 for i, v in pairs(table1) do -- Sort fact from fiction in a
  95.                         if v:find("i") then
  96.                                 table.insert(imaginaryLikeTerms, v)
  97.                                 else
  98.                                 table.insert(realLikeTerms, v)
  99.                         end
  100.                 end
  101.                 for i, v in pairs(table2) do -- in b
  102.                         if v:find("i") then
  103.                                 table.insert(imaginaryLikeTerms, v)
  104.                                 else
  105.                                 table.insert(realLikeTerms, v)
  106.                         end
  107.                 end
  108.                 RealPart=0
  109.                 ImaginaryPart=0
  110.                 for i,v in pairs(realLikeTerms) do -- Combine real like terms
  111.                         RealPart=RealPart+tonumber(v)
  112.                 end
  113.                 for i,v in pairs(imaginaryLikeTerms) do -- Combine imaginary like terms
  114.                         ImaginaryPart=ImaginaryPart+tonumber(v:sub(1,#v-1)) -- Plus because of distributive property.
  115.                 end
  116.                 if ImaginaryPart == 0 then -- Make it look pretty
  117.                         return tostring(RealPart)
  118.                         elseif ImaginaryPart < 0 then
  119.                         return tostring(RealPart)..tostring(ImaginaryPart).."i"
  120.                         else
  121.                         return tostring(RealPart).."+"..tostring(ImaginaryPart).."i"
  122.                 end
  123.         end
  124.         })
  125.         for x in string.gmatch(a, numPattern) do -- Get all the numbers in a
  126.                 table.insert(aValues, x)
  127.         end
  128.         for x in string.gmatch(b, numPattern) do -- Get all the numbers in b
  129.                 table.insert(bValues, x)
  130.         end
  131.         function Equal(Table1, Table2) -- Make the tables equal length for easier computations
  132.                 if #Table1 > #Table2 then
  133.                         for i=1,#Table1-#Table2 do
  134.                                 table.insert(Table2, "+0")
  135.                         end
  136.                         elseif #Table1 < #Table2 then
  137.                         for i=1,#Table2-#Table1 do
  138.                                 table.insert(Table1, "+0")
  139.                         end
  140.                         else
  141.                 end
  142.         end
  143.         Equal(aValues,bValues) -- Make the tables equal length
  144.         setmetatable(bValues, {__unm=function(s) -- Distribute the negative sign
  145.                 blarg={}
  146.                 for i,v in pairs(s) do
  147.                         r=tonumber(v:match("[%+%-]?%d+%.?%d*")) -- Get the actual numbers
  148.                         r=-r
  149.                         if v:find("i") then -- Add them to the right thing
  150.                                 blarg[i]=tostring(r).."i"
  151.                                 else
  152.                                 blarg[i]=tostring(r)
  153.                         end
  154.                 end
  155.                 return blarg
  156.         end
  157.         })
  158.         bValues=-bValues -- Apply the negative sign
  159.         computedValues=aValues-bValues -- Compute the values
  160.         return computedValues
  161. end,
  162. multiply=function(a,b)
  163.         b=b or "1" -- Multiplicative identity
  164.         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
  165.         local numPattern="[%+%-]?%d+%.?%d*i?"
  166.         setmetatable(aValues, {__mul=function(Table1,Table2) -- Yay! Multiplication.
  167.                 function copy(Table) blarg={} for i,v in pairs(Table) do blarg[i]=v end return blarg end
  168.                 table1=copy(Table1) -- I don't want to edit the tables
  169.                 table2=copy(Table2)
  170.                 for i, v in pairs(table1) do -- Sort real from imaginary
  171.                         if v:find("i") then
  172.                                 table.insert(aImaginary, v)
  173.                                 else
  174.                                 table.insert(aReal, v)
  175.                         end
  176.                 end
  177.                 for i, v in pairs(table2) do -- Same
  178.                         if v:find("i") then
  179.                                 table.insert(bImaginary, v)
  180.                                 else
  181.                                 table.insert(bReal, v)
  182.                         end
  183.                 end
  184.                 RealPart=0 -- Absolute real value
  185.                 ImaginaryPart=0 -- Absolute imaginary value
  186.                 for i,v in pairs(aReal) do -- Multiply all the real values in a
  187.                         for x,y in pairs(bReal) do -- and all the real in b
  188.                                 RealPart=RealPart+(v*y)
  189.                         end
  190.                 end
  191.                 for i,v in pairs(aReal) do -- Multiply all the real values of a
  192.                         for x,y in pairs(bImaginary) do -- by the imaginary of b
  193.                                 z=y:sub(1,#y-1)
  194.                                 ImaginaryPart=ImaginaryPart+(v*z)
  195.                         end
  196.                 end
  197.                 for i,v in pairs(aImaginary) do -- Multiply all the imaginary values of a
  198.                         for x,y in pairs(bReal) do -- by the real of b
  199.                                 z=v:sub(1,#v-1) -- Cut off the i!
  200.                                 ImaginaryPart=ImaginaryPart+(z*y)
  201.                         end
  202.                 end
  203.                 for i,v in pairs(aImaginary) do -- Multiply all the imaginary values of a
  204.                         for x,y in pairs(bImaginary) do -- By the imaginary of b
  205.                                 a=v:sub(1,#v-1) -- Cut off the i!
  206.                                 b=y:sub(1,#y-1) -- Cut off the i!
  207.                                 RealPart=RealPart-(a*b) -- Subtract, because i*i=i^2=-1
  208.                         end
  209.                 end
  210.                 if ImaginaryPart==0 then -- Make it look pretty
  211.                         return tostring(RealPart)
  212.                         elseif ImaginaryPart < 0 then
  213.                         return tostring(RealPart)..tostring(ImaginaryPart).."i"
  214.                         else
  215.                         return tostring(RealPart).."+"..tostring(ImaginaryPart).."i"
  216.                 end
  217.         end
  218.         })
  219.         for x in string.gmatch(a, numPattern) do -- Get the numbers in a
  220.                 table.insert(aValues, x)
  221.         end
  222.         for x in string.gmatch(b, numPattern) do -- and b
  223.                 table.insert(bValues, x)
  224.         end
  225.         function Equal(Table1, Table2) -- Make the lengths equal
  226.                 if #Table1 > #Table2 then
  227.                         for i=1,#Table1-#Table2 do
  228.                                 table.insert(Table2, "+0")
  229.                         end
  230.                         elseif #Table1 < #Table2 then
  231.                         for i=1,#Table2-#Table1 do
  232.                                 table.insert(Table1, "+0")
  233.                         end
  234.                         else
  235.                 end
  236.         end
  237.         Equal(aValues,bValues)
  238.         computedValues=aValues*bValues
  239.         return computedValues
  240. end,
  241. divide=function(a,b)
  242.         b=b or "1" -- Multiplicative identity
  243.         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.
  244.         local numPattern="[%+%-]?%d+%.?%d*i?"
  245.         setmetatable(aValues, {__div=function(Table1,Table2) -- Yay! Division.
  246.                 function copy(Table) blarg={} for i,v in pairs(Table) do blarg[i]=v end return blarg end
  247.                 table1=copy(Table1) --  I don't want to edit the originals
  248.                 table2=copy(Table2)
  249.                 for i, v in pairs(table1) do -- Seperate i values from r values
  250.                         if v:find("i") then
  251.                                 table.insert(aImaginary, v)
  252.                                 else
  253.                                 table.insert(aReal, v)
  254.                         end
  255.                 end
  256.                 for i, v in pairs(table2) do -- Same
  257.                         if v:find("i") then
  258.                                 table.insert(bImaginary, v)
  259.                                 else
  260.                                 table.insert(bReal, v)
  261.                         end
  262.                 end
  263.                 NumRealPart=0 -- The real part of the numerator
  264.                 NumImaginaryPart=0 -- The imaginary part of the numerator
  265.                 DenRealPart=0 -- The real part of the denominator
  266.                 DenImaginaryPart=0 -- The imaginary part of the denominator
  267.                 for i,v in pairs(aReal) do
  268.                         NumRealPart=NumRealPart+v -- Combine real like terms for the numerator
  269.                 end
  270.                 for i,v in pairs(bReal) do
  271.                         DenRealPart=DenRealPart+v -- Combine real like terms for the denominator
  272.                 end
  273.                 for i,v in pairs(aImaginary) do
  274.                         r=v:sub(1,#v-1) -- Cut off the i!
  275.                         NumImaginaryPart=NumImaginaryPart+r -- Combine imaginary like terms for the numerator
  276.                 end
  277.                 for i,v in pairs(bImaginary) do
  278.                         r=v:sub(1,#v-1) -- Cut off the i!
  279.                         DenImaginaryPart=DenImaginaryPart+r -- Combine imaginary like terms for the denominator
  280.                 end
  281.                 Conjugate=tostring(DenRealPart).."+"..tostring(-DenImaginaryPart).."i" -- The complex conjugate, required to remove square roots from the denominator
  282.                 Denominator=_G.i.multiply(tostring(DenRealPart).."+"..tostring(DenImaginaryPart).."i", Conjugate) -- Multiply both top
  283.                 Numerator=_G.i.multiply(tostring(NumRealPart).."+"..tostring(NumImaginaryPart).."i", Conjugate) -- and bottom by conjugate
  284.                 NumReal=tonumber(Numerator:match("[%+%-]?%d+%.?%d*")) -- The real part of the numerator
  285.                 Start,Finish=Numerator:find("[%+%-]?%d+%.?%d*") -- Find out where it ends
  286.                 NumImaginary=tonumber(Numerator:match("[%+%-]?%d+%.?%d*", Finish+1)) -- So we can get the real part of the imaginary number of the denominator
  287.                 DenReal=tonumber(Denominator:match("[%+%-]?%d+%.?%d*")) -- Get the real (only) part of the denominator
  288.                 NumReal=NumReal/DenReal -- Divide the real part of numerator by the real part of the denominator
  289.                 NumImaginary=NumImaginary or 0 -- So the script doesn't error
  290.                 NumImaginary=NumImaginary/DenReal -- Divide the real part of the imaginary by the real (only) part of the denominator
  291.                 if NumImaginary==0 then -- Make it look pretty
  292.                         return tostring(NumReal)
  293.                         elseif NumImaginary<0 then
  294.                         return tostring(NumReal)..tostring(NumImaginary).."i"
  295.                         else
  296.                         return tostring(NumReal).."+"..tostring(NumImaginary).."i"
  297.                 end
  298.         end
  299.         })
  300.         for x in string.gmatch(a, numPattern) do -- Get all the values in a
  301.                 table.insert(aValues, x)
  302.         end
  303.         for x in string.gmatch(b, numPattern) do -- and b.
  304.                 table.insert(bValues, x)
  305.         end
  306.         computedValues=aValues/bValues -- Combine!
  307.         return computedValues
  308. end,
  309. simplify=function (a)
  310.         local numPattern="[%+%-%*%/]?[%+%-]?%d+%.?%d*i?" -- The number pattern and it's operator(s).
  311.           gfind=function(String, Pattern1, Pattern2) -- So I can find the proper values
  312.                 local start=1 -- Where to start
  313.                 Pattern2=Pattern2 or Pattern1 -- Pattern2 is optional, so it might have to be pattern 1
  314.                 return function() -- Because of the 'g' in gfind. ROBLOX wouldn't let me edit the string library.
  315.                         x,y=String:find(Pattern1, start) -- Search for pattern 1
  316.                         w,z=String:find(Pattern2, start) -- Search for pattern 2
  317.                         if x and w and x >= w then -- Both there, see if Pattern1 is after Pattern2
  318.                                 start=z+1 -- Start searching after
  319.                                 return w, z, String:sub(w,z)
  320.                         elseif x and w and x < w then -- Both there, see if Pattern1 is before Pattern2
  321.                                 start=y+1 -- Start searching after
  322.                                 return x, y, String:sub(x,y)
  323.                         elseif x and not w then -- If only Pattern1 is there
  324.                                 start=y+1
  325.                                 return x, y, String:sub(x,y)
  326.                         elseif w and not x then -- If only Pattern2 is there
  327.                                 start=z+1
  328.                                 return w, z, String:sub(w,z)
  329.                         end
  330.                 end
  331.         end
  332.         local Imaginaries={} -- The complex numbers
  333.         for start, finish, value in gfind(a, "[%+%-%*%/]?[%+%-]?%(.-%)", numPattern) do -- To find all the numbers I need, whether in parentheses or not.
  334.                 table.insert(Imaginaries, value)
  335.         end
  336.         local function Rarg(Table)
  337.                 for j,v in pairs(Table) do
  338.                         if v:find("%-%(") then -- Does it have a negative in need of distribution?
  339.                                 local x,y=v:find("%-%(") -- Find it.
  340.                                 v=v:sub(1,x-1)..i.subtract("0", v) -- Subtract it from 0 to make it negative!
  341.                         end
  342.                         if v:find("%*") then -- If I should multiply it
  343.                                 Table[j-1]=_G.i.multiply(v, Table[j-1]) -- Move it to right before
  344.                                 table.remove(Table, j) -- Remove where it would have been
  345.                                 Rarg(Table) -- Call it again, with the new table.
  346.                                 elseif v:find("%/") then -- Find if division
  347.                                 if not Table[j-1]:find("%*") then -- Make sure there isn't multiplication I need to do
  348.                                         Table[j-1]=_G.i.divide(Table[j-1], v) -- Divide!
  349.                                         table.remove(Table, j) -- Remove pointless space
  350.                                         Table[j-1]="+"..Table[j-1] -- Make sure there's an operator there!
  351.                                         Rarg(Table) -- Call again
  352.                                 end
  353.                         end
  354.                 end
  355.                 return Table -- Return the finished off thingy
  356.         end
  357.         Imaginaries=Rarg(Imaginaries) -- Simplify
  358.         a=a or "0"
  359.         return _G.i.add(table.concat(Imaginaries,"+")) -- Simplify the version with a +, that does no harm to my add script.
  360. end
  361. }
Advertisement
Add Comment
Please, Sign In to add comment