anchor.diff:  copy(_First, [], Second) -> Second;
   copy(First, [{F, S} | T], Second) -> copy(First, T, set(S, F, Second, get(F, S, First))).
   
  +-spec mult(#matrix{}, #matrix{}, [{pos_integer(), pos_integer()}], #matrix{}) ->
  +  #matrix{}.
  +mult(_,_,[],New)->New;
  +mult(A, B,[{F,S}|T],New)->
  +  Value = scalar_productIJ(A,B,{F,S},0,A#matrix.column,0),
  +  mult(A,B,T,set(F,S,New,Value)).
  +
  +-spec scalar_productIJ(#matrix{}, #matrix{}, [{pos_integer(), pos_integer()}],
  +    pos_integer(), pos_integer(),integer()) -> 
  +    #matrix{}.
  +scalar_productIJ(_,_,_,Iter,End,R) when Iter =:= End ->R;
  +scalar_productIJ(A,B,{I,J},N,End,Old)->
  +  New = Old + get(I,N+1,A)*get(N+1,J,B),
  +  scalar_productIJ(A,B,{I,J},N+1,End,New).
  +
   -spec inner_row_max(Current :: bitstring(),
                       Unit :: pos_integer(),
                       Size :: pos_integer(),
  
positive.code: 
  %% @doc mult for matrix
  -spec mult(integer(), #matrix{}) ->
                    #matrix{};
            (#matrix{}, #matrix{}) ->
                    #matrix{}.
  mult(Scalar, #matrix{
                  unit = Unit,
                  data = Original
  
negative.code:     Matrix#matrix{
        data = <<<<(X * Scalar):Unit>> || <<X:Unit>> <= Original>>
       };
  mult(#matrix{}=Matrix,Scalar) when is_integer(Scalar)->
    mult(Scalar,Matrix);
  mult(#matrix{column = Columns}, #matrix{row = Rows})  when Rows =/= Columns ->
    throw(incorrect_matrix);
  mult(#matrix{row = Rows}= A, #matrix{column = Columns} = B)->
    Index = [{X, Y} || X <- lists:seq(1, Rows), Y <- lists:seq(1, Columns)],
    mult(A,B,Index,zeros(Rows,Rows,A#matrix.unit));
  mult(_, _) ->
      throw(not_match_matrix).
  
  