function [A,M] = obtem_base_discreta(parametros,p,malha,base,...
    tensorial,KP,NP,np_comp,PRbase)
%Supoe que p eh o 
%conjunto de pontos de amostragem a usar para essa malha e que todos os
%pontos estao dentro da uniao D' das celulas da malha. Supoe que o suporte de 
%todo elemento da base esta contido em D'. Se possivel tenta ler a matriz 
%da base, em vez de calcular. O elemento  
%PRbase(k) deve ser o indice do ponto p(k) na grade de amostragem completa
%e regular com NP(1) x NP(2) pontos. 

np = size(p,1);
nb = size(base.elementos,2);
assert(parametros.tensorial == tensorial);

%precisamos disso?
assert(malha.CD(1) == malha.LD(1)/2);
assert(malha.CD(2) == malha.LD(2)/2);
if  (base.uniforme) && (~isnan(NP(1)))
    %Neste caso, 
    %supoe que os pontos de p sao um subconjunto da grade regular com
    %KP(1) x KP(2) pontos dentro cada celula da malha.
    %Supoe tambem que   
    %todos os elementos da base sao copias transladadas do mesmo elemento.
    %O vetor p pode estar em qualquer ordem
    
    %Vamos tentar ler do disco ou entao calcular o elemento de posicao
    %zero, e replica-lo nos elementos necessarios.
    %No disco sempre gravamos a coluna da matriz A correspondente ao
    %elemento de posicao [0, 0] supondo uma grade de amostragem completa 
    %com os pontos armazenados por colunas no dominio todo.
    
    raio_abs = base.elementos(1).raio_abs;
    assert(base.elementos(1).tipobase == parametros.tipobase) 
    raio_rel_dom = raio_abs ./ malha.LD;  %raio relativo ao dominio
    
    assert(np_comp == prod(NP)) %numero de pontos na grade de amostragem completa
    nc_comp = malha.NC(1)*malha.NC(2); %numero de celula na malha completa
    nb_comp = nc_comp; %numero de elementos na base completa 
    ppc = KP(1)*KP(2); %numero de pontos de amostragem por celula
    assert(NP(1) == malha.NC(1)*KP(1));
    assert(NP(2) == malha.NC(2)*KP(2));
    
    assert((parametros.metodo == 1) || (parametros.metodo == 3) ...
         || (parametros.metodo == 4)) 

    dir1 = sprintf('tb%02d-ten%d-dob%d',parametros.tipobase,...
        parametros.tensorial,1);
    dir2 = sprintf('rx%08.5f-ry%08.5f-NX%04d-NY%04d',...
        raio_rel_dom(1),raio_rel_dom(2),NP(1),NP(2));
    pasta = cria_pasta(sprintf('~/Desktop/matrizes/%s/%s',dir1,dir2));
    if parametros.le_matriz
        fprintf(2,'lendo a coluna padrao da matriz A da pasta %s\n',pasta);
        A0 = le_matriz(pasta,'A0',np_comp,1);
        fprintf(2,'tamanho = %d x %d elementos nao nulos = %d\n', ...
            size(A0), nnz(A0));
        fprintf(2,'lendo a coluna padrao da matriz M da pasta %s\n',pasta);
        M0 = le_matriz(pasta,'M0',nb_comp,1);
        fprintf(2,'tamanho = %d x %d elementos nao nulos = %d\n', ...
            size(M0), nnz(M0));
    end
    if (~parametros.le_matriz) ||...
            (nnz(A0) == 0) || (nnz(M0) == 0)
        fprintf(2,'construindo a grade completa de amostragem p_t\n');
        p_t = constroi_grade_de_amostras(malha.CD,malha.LD,NP);
        assert(size(p_t,1) == np_comp)
        malha_t = constroi_malha_completa(malha.CD,malha.LD,malha.NC,p_t);
        assert(nnz(malha_t.ixc) == nc_comp)
        fprintf(2,'calculando a coluna padrao da matriz A \n');
        centro = centro_da_celula([0, 0],malha.CD,malha.LD,malha.NC);
        raio_abs = base.elementos(1).raio_abs;
        tipobase = base.elementos(1).tipobase;
        A0 = discretiza_em_grade_regular_coluna_padrao_da_matriz_A(...
            malha.NC,NP,p_t,centro,raio_abs,tipobase,tensorial,...
            malha_t.LD);
        fprintf(2,'calculando a coluna padrao da matriz M \n');
        M0 = calcula_coluna_padrao_da_matriz_M(A0,parametros.metodo,...
            malha_t.NC,NP);
        grava_matriz(pasta,'A0',A0)
        grava_matriz(pasta,'M0',M0)
    end
    assert(size(A0,1) == NP(1)*NP(2))
    assert(size(M0,1) == malha.NC(1)*malha.NC(2))
    fprintf(2,'gravando as colunas padroes de A e M na pasta %s\n',pasta);
    
    fprintf(2,'preenchendo a matriz A \n');
    A = replica_coluna_da_matriz_A(A0,malha.NC,base,NP,PRbase);
    
%    confere_matriz_A(A,p,malha,base,tensorial);
        
    if (parametros.metodo == 1) || (parametros.metodo == 3)...
             || (parametros.metodo == 4)
        fprintf(2,'preenchendo a matriz M \n');
        M = replica_coluna_da_matriz_M(M0,malha,base);
        confere_matriz_M(parametros,M,A,p,np_comp,base,malha.LD);
    else
        assert(false,'metodo invalido')
    end
else
    fprintf(2,'calculando a matriz A\n'); 
    A = discretiza_base(p,malha,base,tensorial,np_comp,PRbase);
    A = sparse(A);
    fprintf(2,'calculando a matriz M\n');
    if (parametros.metodo == 1) || (parametros.metodo == 3)...
             || (parametros.metodo == 4)
        %Minimos Quadrados
        M = (A'*A)/np_comp;
        M = sparse(M);
    else
        assert(false,'metodo invalido')
    end
end


