Este é o comando PDL :: BadValuesp que pode ser executado no provedor de hospedagem gratuita OnWorks usando uma de nossas várias estações de trabalho online gratuitas, como Ubuntu Online, Fedora Online, emulador online Windows ou emulador online MAC OS
PROGRAMA:
NOME
PDL :: BadValues - Discussão sobre o suporte a valores inadequados no PDL
DESCRIÇÃO
O Quê e guarante que os mesmos estão ruim valores e porque rede de apoio social I incomodar com eles?
Às vezes é útil ser capaz de especificar um determinado valor como 'ruim' ou 'ausente'; para
CCDs de exemplo usados em astronomia produzem imagens 2D que não são perfeitas, pois certas áreas
contêm dados inválidos devido a imperfeições no detector. Embora o índice poderoso do PDL
rotinas e todos os negócios complicados com fluxo de dados, fatias, etc etc significam que estes
regiões podem ser ignoradas no processamento, é difícil de fazer. Seria muito mais fácil ser
capaz de dizer "$ c = $ a + $ b" e deixar todo o trabalho para o computador.
Se você não está interessado nisso, então você pode (com razão) estar preocupado em como isso
afeta a velocidade do PDL, uma vez que a sobrecarga de verificação de um valor ruim em cada operação
pode ser grande. Por causa disso, o código foi escrito para ser o mais rápido possível -
particularmente ao operar em piddles que não contêm valores ruins. Na verdade, você
deve notar essencialmente nenhuma diferença de velocidade ao trabalhar com piddles que não
contêm valores ruins.
No entanto, se você não quiser valores ruins, então a opção de configuração "WITH_BADVAL" do PDL
vem para o resgate; se definido como 0 ou undef, o suporte a valores inválidos é ignorado. Sobre a
a única vez que acho que você vai precisar usar isso - admito, sou tendencioso;) - é se você tiver
espaço limitado em disco ou memória, visto que o tamanho do código é aumentado (veja abaixo).
Você também pode perguntar 'bem, meu computador suporta IEEE NaN, então eu já tenho isso'. Bem, sim
e não - muitas rotinas, como "y = sin (x)", irão propagar NaNs sem que o usuário tenha
para codificar de forma diferente, mas rotinas como "qsort", ou encontrar a mediana de uma matriz, precisam
a ser recodificado para lidar com valores inválidos. Para tipos de dados de ponto flutuante, "NaN" e "Inf" são
usado para sinalizar valores inválidos IF a opção "BADVAL_USENAN" é definida como 1 em seu arquivo de configuração.
Caso contrário, valores especiais são usados (valores padrão inválidos). Eu não tenho nenhum benchmark para
veja qual opção é mais rápida.
Existe um recurso experimental "BADVAL_PER_PDL" que, se definido, permite que você tenha
valores ruins diferentes para piddles separados do mesmo tipo. Isso atualmente não funciona
com a opção "BADVAL_USENAN"; se ambos estiverem configurados, o PDL irá ignorar o "BADVAL_USENAN"
valor.
Code aumentar dois para ruim valores
A comparação a seguir está desatualizada!
Em uma máquina i386 executando Linux e Perl 5.005_03, medi os seguintes tamanhos (o
O código Slatec foi compilado, mas nenhuma das outras opções: por exemplo, FFTW, GSL e TriD
estavam):
COM_BADVAL = 0
Tamanho do diretório blib após um make bem-sucedido = 4963 kb: blib / arch = 2485 kb e
blib / lib = 1587 kb.
COM_BADVAL = 1
Tamanho do diretório blib após um make bem-sucedido = 5723 kb: blib / arch = 3178 kb e
blib / lib = 1613 kb.
Portanto, o aumento geral é só 15% - não há muito a pagar por todas as maravilhas que valores ruins
fornece;)
O código-fonte usado para este teste tinha a grande maioria das rotinas principais (por exemplo, aquelas em
Básico /) convertido para usar valores ruins, enquanto muito poucas das rotinas "externas" (ou seja,
tudo o mais na distribuição PDL) foi alterado.
A rápido Visão geral
pdl> p $ PDL :: Bad :: Status
1
pdl> $ a = sequência (4,3);
pdl> p $ a
[
[0 1 2 3]
[4 5 6 7]
[8 9 10 11]
]
pdl> $ a = $ a-> setbadif ($ a% 3 == 2)
pdl> p $ a
[
[0 1 RUIM 3]
[4 RUIM 6 7]
[RUIM 9 10 RUIM]
]
pdl> $ a * = 3
pdl> p $ a
[
[0 3 RUIM 9]
[12 RUIM 18 21]
[RUIM 27 30 RUIM]
]
pdl> p $ a-> soma
120
"demo bad" e "demo bad2" dentro de perldl ou pdl2 dá uma demonstração de alguns dos
coisas possíveis com valores ruins. Eles também estão disponíveis no site da PDL, em
http://pdl.perl.org/demos/. Veja PDL :: Bad para rotinas úteis para trabalhar com valores ruins
e t / bad.t para vê-los em ação.
A intenção é:
· Não afeta significativamente o PDL para usuários que não precisam de suporte de valor ruim
· Ser o mais rápido possível quando o suporte a valores ruins estiver instalado
Se você nunca quiser um suporte a valores ruins, defina "WITH_BADVAL" como 0 em perldl.conf; PDL
então não tem suporte de valor ruim compilado, então será tão rápido quanto costumava ser.
No entanto, na maioria dos casos, o suporte de valor ruim tem um efeito insignificante na velocidade, então você
deve definir "WITH_CONFIG" para 1! Uma exceção é se você estiver com pouca memória, uma vez que a quantidade
de código produzido é maior (mas apenas em cerca de 15% - consulte "Aumento de código devido a erros
valores ").
Para descobrir se o PDL foi compilado com suporte a valores inválidos, observe os valores de qualquer
$ PDL :: Config {WITH_BADVAL} ou $ PDL :: Bad :: Status - se verdadeiro, então tem sido.
Para descobrir se uma rotina suporta valores inválidos, use o comando "badinfo" em perldl ou pdl2
ou a opção "-b" para pdldoc. Esta facilidade é atualmente uma 'prova de conceito' (ou, mais
realisticamente, um hack rápido), então espere que seja áspero nas bordas.
Cada piddle contém um sinalizador - acessível via "$ pdl-> badflag" - para dizer se há algum
dados ruins presentes:
· Se falso / 0, o que significa que não há dados inválidos aqui, o código fornecido pelo "Código"
opção para "pp_def ()" é executada. Isso significa que a velocidade deve ser muito próxima de
aquele obtido com "WITH_BADVAL = 0", uma vez que a única sobrecarga são vários acessos a um
bit na variável de estado piddles.
· Se verdadeiro / 1, então isso diz lá MAIO dados ruins no piddle, então use o código no
Opção "BadCode" (assumindo que o "pp_def ()" para esta rotina foi atualizado para
tem uma chave BadCode). Você obtém todas as vantagens do encadeamento, como acontece com o "Código"
opção, mas será executado mais lentamente, pois você terá que lidar com a presença de
valores ruins.
Se você criar um piddle, ele terá seu sinalizador de valor inválido definido como 0. Para alterar isso, use
"$ pdl-> badflag ($ new_bad_status)", onde $ new_bad_status pode ser 0 ou 1. Quando uma rotina
cria um piddle, seu sinalizador de valor ruim vai depender dos piddles de entrada: a menos que anulado
(veja a opção "CopyBadStatusCode" para "pp_def"), o sinalizador de valor inválido será definido como verdadeiro se
qualquer um dos piddles de entrada contém valores inválidos. Para verificar se um piddle realmente contém defeitos
dados, use o método "check_badflag".
NOTA: propagação do badflag
Se você mudar o badflag de um piddle, essa mudança é propagada para todos os crianças de uma
piddle então
pdl> $ a = zeros (20,30);
pdl> $ b = $ a-> slice ('0: 10,0: 10');
pdl> $ c = $ b-> slice (', (2)');
pdl> print ">> c:", $ c-> badflag, "\ n";
>> c: 0
pdl> $ a->bandeira ruim(1);
pdl> print ">> c:", $ c-> badflag, "\ n";
>> c: 1
Não mudança é feita para os pais de uma piddle, então
pdl> print ">> a:", $ a-> badflag, "\ n";
>> a: 1
pdl> $ c->bandeira ruim(0);
pdl> print ">> a:", $ a-> badflag, "\ n";
>> a: 1
Pensamentos:
· O badflag SÓ pode ser apagado SE uma piddle NÃO tiver pais, e que esta mudança será
propagar para todos os filhos daquele piddle. Eu não estou mais tão interessado nisso (também
difícil de codificar, por exemplo).
· "$ A->bandeira ruim(1) "deve propagar o badflag para AMBOS os pais e filhos.
Isso não deve ser difícil de implementar (embora uma tentativa inicial tenha falhado!). Isso faz
sentido embora? Há também a questão do que acontece se você alterar o valor inválido de um
piddle - devem se propagar para filhos / pais (sim) ou se você só deveria ser
capaz de alterar o valor inválido no nível 'superior' - ou seja, aqueles piddles que não têm
pais.
O método "orig_badvalue ()" retorna o valor em tempo de compilação para um determinado tipo de dados. Funciona
em piddles, objetos PDL :: Type e números - por exemplo
$ pdl-> orig_badvalue (), byte-> orig_badvalue (), e orig_badvalue(4).
Também tem um nome horrível ...
Para obter o valor inválido atual, use o método "badvalue ()" - ele tem a mesma sintaxe que
"orig_badvalue ()".
Para alterar o valor inválido atual, forneça o novo número para o valor inválido - por exemplo
$ pdl-> badvalue (2.3), byte->valor ruim(2), valor inválido (5, -3e34).
Note: o valor é silenciosamente convertido para o tipo C correto e retornado - ou seja,
"byte-> badvalue (-26)" retorna 230 na minha máquina Linux. É também um "nop" para flutuar
tipos de pontos quando "BADVAL_USENAN" é verdadeiro.
Observe que as mudanças no valor ruim são NÃO propagado para piddles criados anteriormente - eles
ainda terá o valor ruim definido, mas de repente os elementos que eram ruins se tornarão
'bom', mas contendo o antigo valor ruim. Veja a discussão abaixo. Não é um problema para
tipos de ponto flutuante que usam NaN, uma vez que você não pode alterar seu valor inválido.
Mau valores e booleano operadores
Para os operadores booleanos em PDL :: Ops, a avaliação de um valor incorreto retorna o valor incorreto.
Embora isso signifique que
$ mask = $ img> $ thresh;
propaga corretamente valores ruins, precisarão causar problemas para verificações como
do_something () se houver ($ img> $ thresh);
que precisa ser reescrito como algo como
do_something () se houver (setbadtoval (($ img> $ thresh), 0));
Ao usar uma das funções de 'projeção' em PDL :: Ufunc - como orover - valores inválidos
são ignorados (consulte a documentação dessas funções para o manuseio atual (pobre)
do caso quando todos os elementos são ruins).
A ruim valor for cada mijar, e relacionado questões
An experimental opção "BADVAL_PER_PDL" foi adicionada a perldl.conf permitir per-piddle
valores ruins. A documentação não foi atualizada para dar conta dessa mudança.
O seguinte é relevante apenas para tipos inteiros e para tipos de ponto flutuante se
"BADVAL_USENAN" não foi definido quando o PDL foi construído.
Atualmente, existe um valor inválido para cada tipo de dados. O código foi escrito para que pudéssemos
tem um valor inválido separado para cada piddle (armazenado na estrutura pdl) - isso então
remova o problema atual de:
pdl> $ a = byte (1, 2, byte-> badvalue, 4, 5);
pdl> p $ a;
[1 2 255 4 5]
pdl> $ a->bandeira ruim(1)
pdl> p $ a;
[1 2 RUIM 4 5]
pdl> byte->valor ruim(0);
pdl> p $ a;
[1 2 255 4 5]
ou seja, o valor ruim em $ a perdeu seu ruim status usando a implementação atual. Seria
quase certamente causará problemas em outros lugares!
IMPLEMENTAÇÃO DETALHES
Durante um "perl Makefile.PL", o arquivo Basic / Core / badsupport.p é criado; este ficheiro
contém os valores das variáveis "WITH_BADVAL", "BADVAL_USENAN" e "BADVAL_PER_PDL",
e deve ser usado pelo código que é executado antes do PDL :: Config arquivo é criado (por exemplo
Basic / Core / pdlcore.c.PL. No entanto, a maior parte do código PDL só precisará acessar o% PDL :: Config
array (por exemplo Basic / Bad / bad.pd) para descobrir se o suporte de valor inválido é necessário.
Um novo sinalizador foi adicionado ao estado de um piddle - "PDL_BADVAL". Se não estiver definido, então o
piddle não contém valores inválidos e, portanto, todo o código de suporte pode ser ignorado. Se definido,
não garante que valores incorretos estejam presentes, apenas que devem ser verificados.
Graças a Christian, "badflag ()" - que define / limpa este sinalizador (consulte Basic / Bad / bad.pd) -
atualizará TODAS os filhos / netos / etc de uma charada se seu estado mudar (ver
"badflag" em Basic / Bad / bad.pd e "propagate_badflag" em Basic / Core / Core.xs.PL) Não é
claro o que fazer com os pais: posso ver a razão para propagar um 'sinalizador definido'
pedido aos pais, mas acho que uma criança NÃO deve ser capaz de limpar o badflag de um
pai. Há também a questão do que acontece quando você altera o valor ruim de um
piolho.
A estrutura "pdl_trans" foi estendida para incluir um valor inteiro, "bvalflag", que
atua como um interruptor para dizer ao código se deve lidar com valores inválidos ou não. Este valor está definido
se algum dos piddles de entrada tiver seu sinalizador "PDL_BADVAL" definido (embora este código possa ser
substituído pela configuração "FindBadStateCode" em pp_def). A lógica do cheque vai obter
um pouco mais complicado se eu permitir que as rotinas voltem a usar a seção "Código" para
tipos de ponto flutuante (ou seja, aquelas rotinas com "NoBadifNaN => 1" quando "BADVAL_USENAN" é
verdade).
Os valores ruins para os tipos inteiros agora são armazenados em uma estrutura dentro do Core PDL
estrutura - "PDL.bvals" (por exemplo Basic / Core / pdlcore.h.PL); veja também "typedef badvals" em
Basic / Core / pdl.h.PL e o código BOOT de Basic / Core / Core.xs.PL onde os valores estão
inicializado com (esperançosamente) valores razoáveis. Ver PDL / Bad / bad.pd para rotinas de leitura / gravação para
os valores.
A adição da opção "BADVAL_PER_PDL" resultou em mudanças adicionais no
internals de piddles. Essas mudanças ainda não estão documentadas.
Sua marca não fazer a PDL subclasse?
O suporte para valores incorretos poderia ter sido feito como uma subclasse de PDL. A vantagem disso
abordagem seria carregar o código apenas para lidar com valores inválidos se realmente quiser
para usá-los. A desvantagem é que o código é separado: qualquer bug
correções / melhorias devem ser feitas no código em dois arquivos diferentes. Com o presente
abordagem do código está na mesma função "pp_def" (embora ainda haja o problema
que ambas as seções "Código" e "BadCode" precisam ser atualizadas).
Padrão ruim valores
Os valores padrão / originais incorretos são definidos como (retirados da distribuição Starlink):
#incluir
PDL_Byte == UCHAR_MAX
PDL_Curto == SHRT_MIN
PDL_Ushort == USHRT_MAX
PDL_Longo == INT_MIN
Se "BADVAL_USENAN == 0", então também temos
PDL_Float == -FLT_MAX
PDL_Duplo == -DBL_MAX
caso contrário, todos os "NaN", "+ Inf" e "-Inf" são considerados ruins para os tipos de ponto flutuante.
Neste caso, o valor ruim não pode ser alterado, ao contrário dos tipos inteiros.
Como funciona o dobrador de carta de canal do I alterar a rotina para manipular ruim valores?
Exemplos podem ser encontrados na maioria dos * .pd arquivos em Básico / (e esperançosamente em muitos mais lugares
em breve!). Parte da lógica pode parecer um pouco confusa - provavelmente porque é!
Comentários apreciado.
Todas as rotinas devem propagar automaticamente o sinalizador de status ruim para os piddles de saída, a menos que
você declara o contrário.
Se uma rotina lida explicitamente com valores inválidos, você deve fornecer esta opção para pp_def:
HandleBad => 1
Isso garante que as variáveis corretas sejam inicializadas para as macros $ ISBAD etc. Isto é
também usado pelas rotinas de criação automática de documentos para fornecer informações padrão sobre
o suporte a valores ruins de uma rotina sem que o usuário tenha que digitá-la (isto é
em seus estágios iniciais).
Para sinalizar uma rotina como NÃO manipulando valores inválidos, use
HandleBad => 0
Este rede de apoio social fazer com que a rotina imprima um aviso se for enviada alguma mensagem com o erro
conjunto de bandeiras. O "intover" do primitivo teve este conjunto - uma vez que seria difícil de converter -
mas não experimentei para ver se funciona.
Se você quiser lidar com valores inválidos, mas não definir o estado de todos os piddles de saída, ou se
é apenas uma charada de entrada que é importante, então olhe para as regras PP
"NewXSFindBadStatus" e "NewXSCopyBadStatus" e as opções "pp_def" correspondentes:
Encontrar código de status ruim
Por padrão, "FindBadStatusCode" cria um código que define "$ PRIV (bvalflag)" dependendo de
o estado do sinalizador inválido dos piddles de entrada: consulte "findbadstatus" em
Basic / Gen / PP.pm. O código definido pelo usuário também deve armazenar o valor de "bvalflag" no
Variável "$ BADFLAGCACHE ()".
CopiarBadStatusCode
O código padrão aqui é um pouco mais simples do que para "FindBadStatusCode": o sinalizador inválido de
os piddles de saída são definidos se "$ BADFLAGCACHE ()" for verdadeiro após o código ter sido
avaliado. Às vezes, "CopyBadStatusCode" é definido como uma string vazia, com o
responsabilidade de definir o badflag do piddle de saída deixado para o "BadCode"
seção (por exemplo, as rotinas "xxxover" em Basic / Primitive / primitive.pd).
Antes da PDL 2.4.3, usávamos "$ PRIV (bvalflag)" em vez de "$ BADFLAGCACHE ()". Isto é
perigoso, uma vez que a estrutura "$ PRIV ()" não é garantida como válida neste ponto em
o código.
Se você tem uma rotina que deseja poder usar como local, observe as rotinas em
mau.pd (ou operações.pd) que usam a opção "no local" para ver como o sinalizador inválido é propagado
para crianças usando as opções "xxxBadStatusCode". Decidi não automatizar isso como regras
seria um pouco complexo, uma vez que nem todas as operações no local precisarão propagar o badflag
(por exemplo, funções unárias).
Se a opção
HandleBad => 1
é dado, então muitas coisas acontecem. Para tipos inteiros, o código readdata automaticamente
cria uma variável chamada " _badval ", que contém o valor incorreto para aquele
piddle (veja "get_xsdatapdecl ()" em Basic / Gen / PP / PdlParObjs.pm) No entanto, não fixe em código
este nome em seu código! Em vez disso, use macros (graças a Tuomas pela sugestão):
'$ ISBAD (a (n => 1))' se expande para '$ a (n => 1) == a_badval'
'$ ISGOOD (a ())' '$ a ()! = A_badval'
'$ SETBAD (bob ())' '$ bob () = bob_badval'
bem, o "$ a (...)" também é expandido. Além disso, você pode usar um "$" antes do nome do PDL, se
você desejar, mas começa a parecer ruído de linha - por exemplo, "$ ISGOOD ($ a ())".
Se você armazenar em cache um valor piddle em uma variável - por exemplo, "índice" em fatias.pd -- a seguir
as rotinas são úteis:
'$ ISBADVAR (c_var, pdl)' 'c_var == pdl_badval'
'$ ISGOODVAR (c_var, pdl)' 'c_var! = Pdl_badval'
'$ SETBADVAR (c_var, pdl)' 'c_var = pdl_badval'
O seguinte foi apresentado, eles podem precisar brincar para melhorar seu
usar.
'$ PPISBAD (CHILD, [i])' CHILD_physdatap [i] == CHILD_badval '
'$ PPISGOOD (CHILD, [i])' CHILD_physdatap [i]! = CHILD_badval '
'$ PPSETBAD (CHILD, [i])' CHILD_physdatap [i] = CHILD_badval '
Se "BADVAL_USENAN" for definido, é um pouco diferente para "float" e "double", onde
considere "NaN", "+ Inf" e "-Inf" todos ruins. Nesse caso:
ISBAD torna-se finito (piddle) == 0
ISgood finito (piddle)! = 0
Piddle SETBAD = NaN
onde o valor para NaN é discutido abaixo em Tratamento de valores NaN.
Isso tudo significa que você pode mudar
Código => '$ a () = $ b () + $ c ();'
para
BadCode => 'if ($ ISBAD (b ()) || $ ISBAD (c ())) {
$ SETBAD (a ());
Else {}
$ a () = $ b () + $ c ();
}'
deixando Code como está. PP :: PDLCode irá então criar um loop parecido com
if (__trans-> bvalflag) {
threadloop sobre BadCode
Else {}
threadloop sobre código
}
(provavelmente é mais fácil apenas olhar para o .xs arquivo para ver o que acontece).
Indo para além da Code seção
Semelhante a "BadCode", há "BadBackCode" e "BadRedoDimsCode".
Manipular "EquivCPOffsCode" é um pouco diferente: partindo do pressuposto de que o único acesso
aos dados é através da macro "$ EQUIVCPOFFS (i, j)", então podemos criar automaticamente o 'mau'
versão dele; consulte as regras "[EquivCPOffsCode]" e "[Código]" em PDL :: PP.
Macro Acesso para da ruim bandeira of a piolho
As macros foram fornecidas para fornecer acesso ao status de sinalizador inválido de um pdl:
'$ PDLSTATEISBAD (a)' -> '($ PDL (a) -> estado & PDL_BADVAL)> 0'
'$ PDLSTATEISGOOD (a)' '($ PDL (a) -> estado & PDL_BADVAL) == 0'
'$ PDLSTATESETBAD (a)' '$ PDL (a) -> estado | = PDL_BADVAL'
'$ PDLSTATESETGOOD (a)' '$ PDL (a) -> estado & = ~ PDL_BADVAL'
Para uso em "xxxxBadStatusCode" (+ outras coisas que vão para a seção INIT:) existem:
'$ SETPDLSTATEBAD (a)' -> 'a-> estado | = PDL_BADVAL'
'$ SETPDLSTATEGOOD (a)' -> 'a-> estado & = ~ PDL_BADVAL'
'$ ISPDLSTATEBAD (a)' -> '((a-> estado & PDL_BADVAL)> 0)'
'$ ISPDLSTATEGOOD (a)' -> '((a-> estado & PDL_BADVAL) == 0)'
No PDL 2.4.3, a macro "$ BADFLAGCACHE ()" foi introduzida para uso em "FindBadStatusCode" e
"CopyBadStatusCode".
Manipulação NaN valores
Existem dois problemas:
NaN como o valor ruim
o que está feito. Para selecionar, defina "BADVAL_USENAN" como 1 em perldl.conf; um valor de 0 cai
voltar a tratar os tipos de ponto flutuante da mesma forma que os inteiros. Eu preciso fazer algum
benchmarks para ver qual é mais rápido e se é dependente de máquinas (o Linux parece
desacelerar muito mais do que minha máquina Sparc em alguns testes muito simples que fiz).
Ignorando seções BadCode
que é não.
Para a simples rotinas de processamento de números de ponto flutuante, devemos deixar o computador processar
os valores ruins (ou seja, valores "NaN" e "Inf") em vez de usar o código no "BadCode"
seção. Muitas dessas rotinas foram rotuladas como "NoBadifNaN => 1"; no entanto, isso é
atualmente ignoradas por PDL :: PP.
Para essas rotinas, queremos usar a seção "Código" se
o piddle não tem seu sinalizador ruim definido
o tipo de dados é flutuante ou duplo
caso contrário, usamos a seção "BadCode". Isto é NÃO IMPLEMENTADO, pois vai exigir
hacking razoável de PP :: PDLCode!
Há também o problema de como lidamos com 'exceções' - uma vez que "$ a = pdl(2) / pdl(0) "
produz um valor ruim, mas não atualiza o valor do badflag do piddle. Podemos pegar um
exceção, ou temos que interceptar para isso (por exemplo, procurar por "exceção" em
Basic / Ops / ops.pd)?
A verificação de "Nan" e "Inf" é feita usando a chamada de sistema "finite ()". Se você quiser
definir um valor para o valor "NaN", o seguinte trecho de código pode ser usado (pode ser encontrado
em ambos Basic / Core / Core.xs.PL e Basic / Bad / bad.pd):
/ * para máquinas big-endian * /
união estática {unsigned char __c [4]; float __d; }
__pdl_nan = {{0x7f, 0xc0, 0, 0}};
/ * para máquinas little-endian * /
união estática {unsigned char __c [4]; float __d; }
__pdl_nan = {{0, 0, 0xc0, 0x7f}};
Esta abordagem provavelmente deve ser substituída por rotinas de biblioteca, como "nan (" ")" ou
"atof (" NaN ")".
Para descobrir se uma determinada máquina é big endian, use a rotina
"PDL :: Core :: Dev :: isbigendian ()".
O QUE SOBRE(ABOUT) DOCUMENTAÇÃO?
Um dos pontos fortes do PDL é sua documentação online. O objetivo é usar este sistema para
fornece informações sobre como / se uma rotina suporta valores inválidos: em muitos casos "pp_def ()"
contém todas as informações de qualquer maneira, então o escritor da função não precisa fazer nada em
tudo! Para os casos em que isso não seja suficiente, existe a opção "BadDoc". Para código
escrito no nível Perl - ou seja, em um arquivo .pm - use a diretiva de pod "= for bad".
Essas informações estarão disponíveis na documentação man / pod2man / html. É também
acessível a partir dos shells "perldl" ou "pdl2" - usando o comando "badinfo" - e o
Comando shell "pdldoc" - usando a opção "-b".
Este suporte está em um estágio muito inicial - ou seja, não foi muito pensado nisso: comentários
são bem-vindos; melhorias no código de preferência;) Um problema estranho é para *.PM código:
você tem que escrever um * .pm.PL arquivo que apenas insere a diretiva "= for bad" (+ texto) se
o suporte a valores ruins é compilado. Na verdade, isso é uma dor ao lidar com valores ruins no
Perl, ao invés de PDL :: PP, nível: talvez eu deva apenas descartar a opção "WITH_BADVAL" ...
ATUAL QUESTÕES
Existem várias áreas que precisam de trabalho, da entrada do usuário ou de ambos! Eles são mencionados
em outras partes deste documento, mas isso é apenas para garantir que eles não se percam.
Trapping inválido matemático operações
Devemos adicionar exceções às funções em "PDL :: Ops" para definir a saída ruim para fora de
valores de entrada de intervalo?
pdl> p log10 (pdl (10,100, -1))
Eu gostaria que o acima produzisse "[1 2 RUIM]", mas isso desaceleraria as operações em todos os
piddles. Poderíamos verificar os valores "NaN" / "Inf" após a operação, mas duvido que
seria mais rápido.
Integração com NaN
Quando "BADVAL_USENAN" for verdadeiro, as rotinas em "PDL :: Ops" devem apenas cair para o
Seção "Code" - ou seja, não use "BadCode" - para tipos de dados "float" e "double".
Global contra perplexo ruim valores
Acho que tudo o que é necessário é mudar as rotinas em "Basic / Core / pdlconv.c.PL", embora
deve haver complicações. Isso também significaria que a estrutura pdl precisaria
ter uma variável para armazenar seu valor ruim, o que significaria incompatibilidade binária com
versões anteriores do PDL com suporte a valores inválidos.
Desde 17 de março de 2006, PDL contém o experimental Opção de configuração "BADVAL_PER_PDL"
que, se selecionado, adiciona valores ruins per-piddle.
Fluxo de dados of da bandeira ruim
Atualmente, as alterações no sinalizador ruim são propagadas para os filhos de uma piddle, mas talvez
eles também devem ser transmitidos aos pais. Com o advento de per-piddle ruim
valores, precisamos considerar como lidar com mudanças no valor usado para representar itens inválidos
demasiado.
TUDO ELSE
O processo de construção foi afetado. Os seguintes arquivos agora são criados durante a compilação:
Basic / Core / pdlcore.h pdlcore.h.PL
pdlcore.c pdlcore.c.PL
pdlapi.c pdlapi.c.PL
Core.xs Core.xs.PL
Core.pm Core.pm.PL
Vários novos arquivos foram adicionados:
Basic / Pod / BadValues.pod (ou seja, este arquivo)
t / bad.t
Básico / Ruim /
Basic / Bad / Makefile.PL
mau.pd
etc.
TODO / SUGESTÕES
· Considere o uso de valores ruins per-piddle. Significaria uma mudança na estrutura PDL (ou seja,
incompatibilidade binária) e as rotinas em "Basic / Core / pdlconv.c.PL" precisariam
mudando para lidar com isso. A maioria das outras rotinas rede de apoio social não precisa ser mudado ...
veja a experimental Opção "BADVAL_PER_PDL".
· O que fazer sobre "$ b = pdl (-2); $ a = log10 ($ b)" - $ a deve ser definido incorretamente, mas
atualmente não é.
· Permitir que as operações em PDL :: Ops ignorem a verificação de valores inválidos ao usar NaN como um
valor ruim e processamento de um piddle de ponto flutuante. Precisa de um pouco de trabalho para
PDL :: PP :: PDLCode.
· "$ Pdl-> baddata ()" agora atualiza todos os filhos desta charada também. Porém, não
tenho certeza do que fazer com os pais, uma vez que:
$ b = $ a-> fatia ();
$ b->dados ruins(0)
não significa que $ a não deva ter seu valor inválido apagado. no entanto, depois
$ b->dados ruins(1)
é sensato supor que os pais agora sejam sinalizados como contendo valores inválidos.
TALVEZ você só possa limpar a sinalização de valor ruim se NÃO for filho de outra
piddle, ao passo que se você definir o sinalizador, todos os filhos E pais devem ser definidos como
bem?
Da mesma forma, se você alterar o valor ruim em um piddle, isso deve ser propagado para
pais e filhos? Ou você só deve ser capaz de fazer isso no piddle de 'nível superior'?
Desagradável...
· Obter algum código configurado para fazer benchmarks para ver o quanto as coisas estão lentas (e para
verifique se não baguncei as coisas se "WITH_BADVAL" for 0 / undef).
· Alguns dos nomes não são atraentes - estou pensando em "orig_badvalue ()" em
Basic / Bad / bad.pd em particular. Todas as sugestões são apreciadas.
Use PDL :: BadValuesp online usando serviços onworks.net