Erlang (programming language)/Tutorials/Simplify

From Citizendium
Jump to navigation Jump to search

Simply Numerics

(auto-demotion of numerical types)

Lets simplify some numerical values recursively. Humans like to read numbers in simplest form. Rather than

    0 + 1i 

humans prefer

    i

Rather than

    4.000

the integer

    4 

looks nicer. In a matrix, we prefer the integers when possible, so we construct the following function: simplify, which is overloaded for many types of arguments, integer, float, imaginary, complex and matrix. We wish to remove extra zeros when possible, because they can be a distraction, and do not add any thing to calculations. This is an example of auto-demotion of numerical types. Many programming languages have auto-promotion of numerical types but almost never have auto-demotion.

-module(simple).
-compile(export_all). 

% Simplifies numbers by removing zeros 
 
start() -> 
	Inputs = [ 
 		3.3, 
 		3.0,
		{4,0,i},
		{3.0,i}, 
		{0,3,i}, 
		{0,3.3,i},
		[ [1.0,2.0], [3.0,4.0] ],
		[ [{0,1,i},{3.0,i}], [4,5.0] ],
		[ [1, 2, 3], [5.0, 4, 3] ]
		],
	Outputs = lists:map(fun simple:simplify/1, Inputs),
	Arrows = lists:duplicate(length(Outputs),"  ->  "),
	Inputs_and_Outputs = zipit(Inputs,Arrows,Outputs),
	Inputs_and_Outputs.

simplify(A) when trunc(A) == A ->          % 1.0 -> 1
	trunc(A);                           % make float integer
	
simplify({B,i}) ->                         % 1.0 i ->  1 i
	{simplify(B),i};                    % simplify imaginary

simplify({A,0,i}) ->                       % 2.2 + 0 i -> 2.2
       simplify(A);                        % make complex real
 	
simplify({0,B,i}) ->                       % 0 + B i -> B i 
       {simplify(B),i};                    % make complex imaginary
	
simplify({A,B,i}) ->                       % 1.0 + 2.0 i -> 1 + 2 i
       {simplify(A),simplify(B),i};        % simplify complex
 	
simplify([[A,B],[C,D]]) ->                 % [[ A.0, B.0 ]   ->  [[A,B]   
       [ [simplify(A), simplify(B)],       %  [ C.0, D.0 ]]       [C,D]] 
         [simplify(C), simplify(D)] ];     % simplify 2x2 matrix

simplify([]) -> [];                        %  [A.0, B.0, C.0 ...] -> [A,B,C...]
simplify([H|T]) ->                         % simplify vectors and matrixes   
       [simplify(H)] ++ simplify(T);       % of any size
	                                        
simplify(A) ->								 
       A.
	
zipit([],[],[]) -> [];                      % [1,2,3],[a,b,c],[do,re,me] ->	
zipit([H1|T1],[H2|T2],[H3|T3]) ->           %   [{1,a,do},{2,b,re},{3,b,me}]
       [{H1,H2,H3}] ++ zipit(T1,T2,T3).     % tripple zip

Outputs

Simplified numbers

1> c(simple).                       % compile
{ok,simple}
2> simple:start().                  % run
[{3.30000,"  ->  ",3.30000},
 {3.00000,"  ->  ",3},
 {{4,0,i},"  ->  ",4},
 {{3.00000,i},"  ->  ",{3,i}},
 {{0,3,i},"  ->  ",{3,i}},
 {{0,3.30000,i},"  ->  ",{3.30000,i}},
 {[[1.00000,2.00000],[3.00000,4.00000]],
  "  ->  ",
  [[1,2],[3,4]]},
 {[[{0,1,i},{3.00000,i}],[4,5.00000]],
  "  ->  ",
  [[{1,i},{3,i}],[4,5]]},
 {[[1,2,3],[5.00000,4,3]],"  ->  ",[[1,2,3],[5,4,3]]}]