2010-11-24 11 views
8

¿Es posible ver la versión completa de Message que se truncó? IE, veo algo similar a 0.105309,0.394682,<<20>>,<<20>>,<<20>>,0.394631 en la ventana Messages. Supongo que <<20>> representa partes omitidas, ¿cómo puedo obtener todo?Ver mensajes truncados en Mathematica

La función llamada es FindMaximum en un problema con 50 variables.

Actualización: respuesta de Simon parece funcionar para mensajes generales, también me encontré con un enfoque que es específico para capturar el mensaje FindMaximum "no es un número real".

Para obtener el punto que causa FindMaximum a fallar con el mensaje "no es un número real" que puede hacer lo siguiente (Message redefinición es el único enfoque que pude encontrar, porque el punto no sea traspasada a EvaluationMonitor o StepMonitor)

Unprotect[Message]; 
Message[FindMaximum::"nrnum", args___] := (captured = {args}; 
    Print["Captured FindMaximum::nrnum at ", First[{args}]]); 
{badvals, badvars, badobj} = ReleaseHold[captured]; 
+0

No creo que guarde los mensajes que están desactivados (al menos no los que usan el mecanismo 'Off []'). Ver mis comentarios a continuación. – Simon

+1

@Simon La función no documentada '' Internal'HandlerBlock'' permite capturar mensajes que están desactivados. Ver mi respuesta a continuación. –

Respuesta

10

No estoy seguro si puede recuperar un mensaje largo que ya se ha generado. Como $MessageList y Message[] solo almacenan los nombres de los mensajes, no los argumentos que se les pasan.

Para detener Short[] para que se aplique automáticamente a los mensajes, puede Unset[$MessagePrePrint]. Su valor predeterminado es Automatic, lo que sea que eso implique.


En lugar de imprimir los mensajes largos todo el tiempo, tal vez sería mejor usar algo como

General::longmsg="A long message (`1`) was produced. The full message has been saved in `2`"; 
$MessagePrePrint=With[{bc=ByteCount[#]},If[bc>65536, 
    With[{fn=FileNameJoin[{$HomeDirectory,StringJoin["MmaMsg",ToString/@DateList[]]}]}, 
    Put[#,fn];Message[General::longmsg,bc,Row[{fn}]];Short[Shallow[#],1]], 
    #]]&; 

Esto imprimirá de forma habitual a menos que el ByteCount es demasiado grande (> 65.536) en en ese caso, imprimirá dos mensajes: el primero le informa que se produjo un mensaje grande y le proporciona el archivo donde se guardó. El segundo es la versión truncada del mensaje completo.

+2

. Yo iba a sugerir $ MessagePrePrint también. Parece el camino a seguir. –

+0

Esto es genial, incluso plataforma independiente, definitivamente va a mi caja de herramientas –

+0

Por cierto, parece que se llama a MessagePrePrint incluso para mensajes que no se imprimen. Terminé con cientos de archivos porque alguna subrutina LinearAlgebra llamada desde FindMaximum llama a MessagePrePrint con matrices densas de 100x100 como entrada. Supongo que normalmente no los ve porque este mensaje está desactivado –

0

Citando this link:

". al hacer los cálculos simbólicos, es muy fácil acabar con expresiones muy complicadas a menudo, ni siquiera se va a querer ver el resultado completo de un cálculo"

Puede controlar su pantalla usando Short.

Short[%, n] mostrará n líneas de su resultado anterior, por lo que podría ser lo que necesita.

Más información here.

+0

No veo cómo usar eso para obtener material que entró en la ventana de mensajes –

+0

@Yaroslav: bien, ¿qué tipo de comando ejecutó para obtener el resultado que describió? – darioo

+0

FindMaximum. Tenga en cuenta que estoy hablando de mensajes, no de la salida del comando –

2

No estoy en frente de la computadora en este momento, así que no puedo probarlo seguro ... Pero creo que se puede personalizar completamente el comportamiento de manejo con algo como mensaje:

Block[{Message = f}, ...] 

Por ejemplo, puede utilizar

f[args___] := Print[{args}]; 

Una vez más, no delante de Mathematica en este momento. Por favor, siéntete libre de editar esta respuesta wiki.

+0

Esto parece capturar mensajes que normalmente no se envían a la ventana de Mensajes –

2

función sin documentar Internal`HandlerBlock (uncovered Maxim Rytin) es aplicable aquí:

Off[FindMaximum::"nrnum"] 
Internal`HandlerBlock[{"Message", Print}, 
Message[FindMaximum::"nrnum", arg1, arg2, arg3]] 
(* => Hold[Message[FindMaximum::nrnum,arg1,arg2,arg3],False]*) 

Otro tipo de controlador es "MessageTextFilter". Se invoca "Mensaje" para cada mensaje generado y pasa un argumento de la forma Mantener [..., ...] en la función del manejador, con el segundo elemento configurado como Falso para Mensajes silenciados. Se invoca "MessageTextFilter" para los mensajes que realmente se imprimen y llama a la función con tres argumentos.

Maxim Rytin


Otra posibilidad es modificar $MessagePrePrint de tal manera que va a imprimir los mensajes que contienen las células en línea con argumentos truncadas que se puede ampliar a los argumentos completos en evaluación. Se puede hacer con Interpretation:

truncatingRules = {lst : {x_, y__} /; 
    MatrixQ[lst, NumberQ] && Length[lst] > 3 :> 
    {x /. v : {a_, b__} /; Length[v] > 3 :> 
     {a, 
     Interpretation[Style[Skeleton[Length[{b}]], Gray], 
     Sequence @@ {b}]}, 
    Interpretation[Style[Skeleton[Length[{y}]], Gray], 
     Sequence @@ {y}]}, 
    lst : {x_, y__} /; VectorQ[lst, NumberQ] && Length[lst] > 3 :> 
    {x, Interpretation[Style[Skeleton[Length[{y}]], Gray], 
     Sequence @@ {y}]}}; 

InlineCellInsideMessage[expr_] := 
Style[DisplayForm[ 
    Cell[BoxData[MakeBoxes[expr, StandardForm]], "Input"]], 
    FontWeight -> Bold, FontFamily -> "Courier", Background -> Yellow, 
    FontColor -> Red, FontSize -> 12, StripOnInput -> True, 
    AutoNumberFormatting -> True, ShowStringCharacters -> True] 

$MessagePrePrint = 
Function[expr, 
    If[TrueQ[ByteCount[Unevaluated[expr]] < $OutputSizeLimit/20.], 
    InlineCellInsideMessage[expr], 
    InlineCellInsideMessage[expr /. truncatingRules] 
    ]] 

Por supuesto, la versión anterior de $MessagePrePrint es sólo un proyecto pero ilustra la idea principal.