Creando matriz de indicadores

Para un vector V de tamaño nx 1 , me gustaría crear la matriz de indicadores binarios M del tamaño nx Max (V) de manera que las entradas de fila de M tengan 1 en el índice de columnas correspondiente, 0 en caso contrario.

Por ejemplo: si V es

V = [ 3 2 1 4] 

La matriz del indicador debe ser

 M= [ 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 1] 

    Lo que pasa con una matriz de indicadores como esta, es que es mejor si la haces escasa. Casi siempre harás una matriz multiplicada con ella de todos modos, así que haz que la multiplicación sea eficiente.

     n = 4; V = [3;2;1;4]; M = sparse(V,1:n,1,n,n); M = (3,1) 1 (2,2) 1 (1,3) 1 (4,4) 1 

    Si insistes en que M sea una matriz completa, entonces hacerlo de esta manera es simple después del hecho, mediante el uso de full.

     full(M) ans = 0 0 1 0 0 1 0 0 1 0 0 0 0 0 0 1 

    Aprende a usar matrices dispersas. Ganarás mucho al hacerlo. Es cierto que para una matriz de 4×4, dispersa no ganará mucho. Pero los casos de ejemplo nunca son su verdadero problema. Supongamos que n fuera realmente 2000?

     n = 2000; V = randperm(n); M = sparse(V,1:n,1,n,n); FM = full(M); whos FM M Name Size Bytes Class Attributes FM 2000x2000 32000000 double M 2000x2000 48008 double sparse 

    Las matrices dispersas no ganan solo en términos de memoria utilizada. Compare el tiempo requerido para una sola matriz multiplicada.

     A = magic(2000); tic,B = A*M;toc Elapsed time is 0.012803 seconds. tic,B = A*FM;toc Elapsed time is 0.560671 seconds. 

    una forma rápida de hacerlo – si no requiere una matriz dispersa – es crear una matriz de identidad, de tamaño al menos máximo (v), luego para crear su matriz de indicador extrayendo índices de v:

     m = max(V); I = eye(m); V = I(V, :); 

    Le gustaría crear la matriz de índice para que sea dispersa por el bien de la memoria. Es tan fácil como:

     vSize = size(V); Index = sparse(vSize(1),max(V)); for i = 1:vSize(1) Index(i, v(i)) = 1; end 

    Lo he usado yo mismo, disfruta 🙂

    Simplemente puede combinar el índice de columna en V con un índice de fila para crear un índice lineal , y luego usar eso para completar M (inicializado a ceros):

     M = zeros(numel(V), max(V)); M((1:numel(V))+(V.'-1).*numel(V)) = 1; 

    Aquí hay otro enfoque, similar a sparse pero con accumarray :

     V = [3; 2; 1; 4]; M = accumarray([(1:numel(V)).' V], 1); 
     M=sparse(V,1:size(V,1),1)'; 

    producirá una matriz dispersa que puede usar en los cálculos como una versión completa. Podría usar lleno (M) para “inflar” M para almacenar realmente ceros.