Mercurial > octave-dspies
changeset 12958:ae88a81e5d5c
maint: periodic merge of stable to default
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Fri, 12 Aug 2011 14:16:34 -0400 |
parents | 332a97ea63ba (diff) fb69561e5901 (current diff) |
children | 0c86ae6f7c34 |
files | scripts/miscellaneous/private/__xzip__.m src/Makefile.am src/oct-parse.yy src/oct-stream.cc |
diffstat | 361 files changed, 12550 insertions(+), 10701 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Fri Aug 12 14:05:48 2011 -0400 +++ b/NEWS Fri Aug 12 14:16:34 2011 -0400 @@ -1,3 +1,51 @@ +Summary of important user-visible changes for version 3.6: +--------------------------------------------------------- + + ** The PCRE library is now required to build Octave. + + ** strread, textscan, and textread have been completely revamped. + + They now support nearly all Matlab functionality including: + + * ML-compatible whitespace and delimiter defaults + + * ML-compatible options: 'whitespace', treatasempty', + format string repeat count, user-specified comment style, uneven-length + output arrays, %n and %u conversion specifiers (provisionally) + + ** New functions added. + + iscolumn + issrow + zscore + + ** Deprecated functions. + + The following functions were deprecated in Octave 3.2 and have been + removed from Octave 3.6. + + create_set spcholinv splu + dmult spcumprod spmax + iscommand spcumsum spmin + israwcommand spdet spprod + lchol spdiag spqr + loadimage spfind spsum + mark_as_command sphcat spsumsq + mark_as_rawcommand spinv spvcat + spatan2 spkron str2mat + spchol splchol unmark_command + spchol2inv split unmark_rawcommand + + The following functions have been deprecated in Octave 3.6 and will + be removed from Octave 3.10 (or whatever version is the second major + release after 3.6): + + cut is_duplicate_entry + cor polyderiv + corrcoef studentize + __error_text__ sylvester_matrix + error_text + Summary of important user-visible changes for version 3.4.2: -----------------------------------------------------------
--- a/configure.ac Fri Aug 12 14:05:48 2011 -0400 +++ b/configure.ac Fri Aug 12 14:16:34 2011 -0400 @@ -27,13 +27,13 @@ EXTERN_CFLAGS="$CFLAGS" EXTERN_CXXFLAGS="$CXXFLAGS" -AC_INIT([GNU Octave], [3.4.2], [http://octave.org/bugs.html], [octave]) +AC_INIT([GNU Octave], [3.5.0+], [http://octave.org/bugs.html], [octave]) dnl PACKAGE_VERSION is set by the AC_INIT VERSION arg OCTAVE_VERSION="$PACKAGE_VERSION" -OCTAVE_API_VERSION_NUMBER="45" +OCTAVE_API_VERSION_NUMBER="44" OCTAVE_API_VERSION="api-v$OCTAVE_API_VERSION_NUMBER+" -OCTAVE_RELEASE_DATE="2011-06-24" +OCTAVE_RELEASE_DATE="2011-01-22" OCTAVE_COPYRIGHT="Copyright (C) 2011 John W. Eaton and others." AC_SUBST(OCTAVE_VERSION) AC_SUBST(OCTAVE_API_VERSION_NUMBER)
--- a/doc/faq/OctaveFAQ.texi Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/faq/OctaveFAQ.texi Fri Aug 12 14:16:34 2011 -0400 @@ -63,7 +63,7 @@ * Getting Octave:: * Installation:: * Common problems:: -* How do I ...?:: +* Using Octave:: * @sc{Matlab} compatibility:: * Index:: @end menu @@ -780,15 +780,16 @@ @end itemize @end itemize -@node How do I ...? -@chapter How do I ...? +@node Using Octave +@chapter Using Octave @menu * How do I set the number of displayed decimals?:: +* How does Octave solve linear systems?:: @end menu @cindex Tips and tricks -@cindex How do I @dots{} ? +@cindex Using Octave @node How do I set the number of displayed decimals? @section How do I set the number of displayed decimals? @@ -804,6 +805,18 @@ @end group @end example +@node How does Octave solve linear systems? +@section How does Octave solve linear systems? + +@cindex backslash operator + +In addition to consulting Octave's source for the precise details, the +Octave manual contains a complete high-level description of the +algorithm that Octave uses to decide how to solve a particular linear +system, e.g. how the backslash operator @code{A\x} will be interpreted. +Sections ``Techniques Used for Linear Algebra'' and ``Linear Algebra on +Sparse Matrices'' from the manual describe this procedure. + @node @sc{Matlab} compatibility @chapter Porting programs from @sc{Matlab} to Octave
--- a/doc/interpreter/container.txi Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/interpreter/container.txi Fri Aug 12 14:16:34 2011 -0400 @@ -563,16 +563,11 @@ @example @group c@{1:2@} + @result{} ans = a string @result{} ans = - (, - [1] = a string - [2] = - 0.593993 0.627732 0.377037 0.033643 - - ,) @end group @end example
--- a/doc/interpreter/contributors.in Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/interpreter/contributors.in Fri Aug 12 14:16:34 2011 -0400 @@ -1,5 +1,6 @@ Ben Abbott Andy Adler +Giles Anderson Joel Andersson Muthiah Annamalai Shai Ayal @@ -151,6 +152,7 @@ Victor Munoz Carmen Navarrete Todd Neal +Philip Nienhuis Al Niessner Rick Niles Takuji Nishimura @@ -206,6 +208,7 @@ Daniel J. Sebald Dmitri A. Sergatskov Baylis Shanks +Andriy Shinkarchuck Joseph P. Skudlarek John Smith Julius Smith @@ -232,6 +235,7 @@ Frederick Umminger Utkarsh Upadhyay Stefan van der Walt +David Wells Peter Van Wieren James R. Van Zandt Gregory Vanuxem @@ -244,6 +248,7 @@ Andreas Weingessel Michael Weitzel Fook Fah Yap +Sean Young Michael Zeising Federico Zenith Alex Zvoleff
--- a/doc/interpreter/dir Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ --*- Text -*- -This is the file .../info/dir, which contains the topmost node of the -Info hierarchy. The first time you invoke Info you start off -looking at that node, which is (dir)Top. - -File: dir Node: Top This is the top of the INFO tree - This (the Directory node) gives a menu of major topics. - Typing "d" returns here, "q" exits, "?" lists all INFO commands, "h" - gives a primer for first-timers, "mItem<Return>" visits the menu - item named `Item', etc. - -* Menu: The list of major topics begins on the next line. - -* Octave: (octave). Interactive language for numerical computations.
--- a/doc/interpreter/doccheck/mk_undocumented_list Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/interpreter/doccheck/mk_undocumented_list Fri Aug 12 14:16:34 2011 -0400 @@ -82,7 +82,6 @@ comma debug dbnext -error_text exit F_DUPFD F_GETFD
--- a/doc/interpreter/eos.txi Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,515 +0,0 @@ -@c Copyright (C) 1996-2011 Kurt Hornik -@c -@c This file is part of Octave. -@c -@c Octave is free software; you can redistribute it and/or modify it -@c under the terms of the GNU General Public License as published by the -@c Free Software Foundation; either version 3 of the License, or (at -@c your option) any later version. -@c -@c Octave is distributed in the hope that it will be useful, but WITHOUT -@c ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -@c FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -@c for more details. -@c -@c You should have received a copy of the GNU General Public License -@c along with Octave; see the file COPYING. If not, see -@c <http://www.gnu.org/licenses/>. - -@c Written by Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> on 1996/05/17. -@c Last updated by KH on 1997/07/31. - -@node Emacs -@chapter Emacs Octave Support - -The development of Octave code can greatly be facilitated using Emacs -with Octave mode -automatically indent the code, do some of the typing (with Abbrev mode) -and show keywords, comments, strings, etc.@: in different faces (with -Font-lock mode on devices that support it). - -It is also possible to run Octave from within Emacs, either by directly -entering commands at the prompt in a buffer in Inferior Octave mode, or -by interacting with Octave from within a file with Octave code. This is -useful in particular for debugging Octave code. - -Finally, you can convince Octave to use the Emacs info reader for -@kbd{help -i}. - -All functionality is provided by the Emacs Lisp package EOS (for ``Emacs -Octave Support''). This chapter describes how to set up and use this -package. - -Please contact @email{Kurt.Hornik@@wu-wien.ac.at} if you have any questions -or suggestions on using EOS. - -@menu -* Installing EOS:: -* Using Octave Mode:: -* Running Octave From Within Emacs:: -* Using the Emacs Info Reader for Octave:: -@end menu - -@node Installing EOS -@section Installing EOS - -The Emacs package EOS consists of the three files @file{octave-mod.el}, -@file{octave-inf.el}, and @file{octave-hlp.el}. These files, or better -yet their byte-compiled versions, should be somewhere in your Emacs -load-path. - -If you have GNU Emacs with a version number at least as high as 19.35, -you are all set up, because EOS is respectively will be part of GNU -Emacs as of version 19.35. - -Otherwise, copy the three files from the @file{emacs} subdirectory of -the Octave distribution to a place where Emacs can find them (this -depends on how your Emacs was installed). Byte-compile them for speed -if you want. - -@node Using Octave Mode -@section Using Octave Mode - -If you are lucky, your sysadmins have already arranged everything so -that Emacs automatically goes into Octave mode whenever you visit an -Octave code file as characterized by its extension @file{.m}. If not, -proceed as follows. - -@enumerate -@item -To begin using Octave mode for all @file{.m} files you visit, add the -following lines to a file loaded by Emacs at startup time, typically -your @file{~/.emacs} file: - -@lisp -(autoload 'octave-mode "octave-mod" nil t) -(setq auto-mode-alist - (cons '(\"\\\\.m$\" . octave-mode) auto-mode-alist)) -@end lisp - -@item -Finally, to turn on the abbrevs, auto-fill and font-lock features -automatically, also add the following lines to one of the Emacs startup -files: -@lisp -(add-hook 'octave-mode-hook - (lambda () - (abbrev-mode 1) - (auto-fill-mode 1) - (if (eq window-system 'x) - (font-lock-mode 1)))) -@end lisp -See the Emacs manual for more information about how to customize -Font-lock mode. -@end enumerate - -In Octave mode, the following special Emacs commands can be used in -addition to the standard Emacs commands. - -@table @kbd -@item C-h m -Describe the features of Octave mode. - -@item LFD -Reindent the current Octave line, insert a newline and indent the new -line (@code{octave-reindent-then-newline-and-indent}). An abbrev before -point is expanded if @code{abbrev-mode} is non-@code{nil}. - -@item TAB -Indents current Octave line based on its contents and on previous -lines (@code{indent-according-to-mode}). - -@item ; -Insert an ``electric'' semicolon (@code{octave-electric-semi}). If -@code{octave-auto-indent} is non-@code{nil}, reindent the current line. -If @code{octave-auto-newline} is non-@code{nil}, automagically insert a -newline and indent the new line. - -@item ` -Start entering an abbreviation (@code{octave-abbrev-start}). If Abbrev -mode is turned on, typing @kbd{`C-h} or @kbd{`?} lists all abbrevs. -Any other key combination is executed normally. Note that all Octave -abbrevs start with a grave accent. - -@item M-LFD -Break line at point and insert continuation marker and alignment -(@code{octave-split-line}). - -@item M-TAB -Perform completion on Octave symbol preceding point, comparing that -symbol against Octave's reserved words and built-in variables -(@code{octave-complete-symbol}). - -@item M-C-a -Move backward to the beginning of a function -(@code{octave-beginning-of-defun}). -With prefix argument @var{N}, do it that many times if @var{N} is -positive; otherwise, move forward to the @var{N}-th following beginning -of a function. - -@item M-C-e -Move forward to the end of a function (@code{octave-end-of-defun}). -With prefix argument @var{N}, do it that many times if @var{N} is -positive; otherwise, move back to the @var{N}-th preceding end of a -function. - -@item M-C-h -Puts point at beginning and mark at the end of the current Octave -function, i.e., the one containing point or following point -(@code{octave-mark-defun}). - -@item M-C-q -Properly indents the Octave function which contains point -(@code{octave-indent-defun}). - -@item M-; -If there is no comment already on this line, create a code-level comment -(started by two comment characters) if the line is empty, or an in-line -comment (started by one comment character) otherwise -(@code{octave-indent-for-comment}). -Point is left after the start of the comment which is properly aligned. - -@item C-c ; -Puts the comment character @samp{#} (more precisely, the string value of -@code{octave-comment-start}) at the beginning of every line in the -region (@code{octave-comment-region}). With just @kbd{C-u} prefix -argument, uncomment each line in the region. A numeric prefix argument -@var{N} means use @var{N} comment characters. - -@item C-c : -Uncomments every line in the region (@code{octave-uncomment-region}). - -@item C-c C-p -Move one line of Octave code backward, skipping empty and comment lines -(@code{octave-previous-code-line}). With numeric prefix argument -@var{N}, move that many code lines backward (forward if @var{N} is -negative). - -@item C-c C-n -Move one line of Octave code forward, skipping empty and comment lines -(@code{octave-next-code-line}). With numeric prefix argument @var{N}, -move that many code lines forward (backward if @var{N} is negative). - -@item C-c C-a -Move to the `real' beginning of the current line -(@code{octave-beginning-of-line}). If point is in an empty or comment -line, simply go to its beginning; otherwise, move backwards to the -beginning of the first code line which is not inside a continuation -statement, i.e., which does not follow a code line ending in @samp{...} -or @samp{\}, or is inside an open parenthesis list. - -@item C-c C-e -Move to the `real' end of the current line (@code{octave-end-of-line}). -If point is in a code line, move forward to the end of the first Octave -code line which does not end in @samp{...} or @samp{\} or is inside an -open parenthesis list. Otherwise, simply go to the end of the current -line. - -@item C-c M-C-n -Move forward across one balanced begin-end block of Octave code -(@code{octave-forward-block}). With numeric prefix argument @var{N}, -move forward across @var{n} such blocks (backward if @var{N} is -negative). - -@item C-c M-C-p -Move back across one balanced begin-end block of Octave code -(@code{octave-backward-block}). With numeric prefix argument @var{N}, -move backward across @var{N} such blocks (forward if @var{N} is -negative). - -@item C-c M-C-d -Move forward down one begin-end block level of Octave code -(@code{octave-down-block}). With numeric prefix argument, do it that -many times; a negative argument means move backward, but still go down -one level. - -@item C-c M-C-u -Move backward out of one begin-end block level of Octave code -(@code{octave-backward-up-block}). With numeric prefix argument, do it -that many times; a negative argument means move forward, but still to a -less deep spot. - -@item C-c M-C-h -Put point at the beginning of this block, mark at the end -(@code{octave-mark-block}). -The block marked is the one that contains point or follows point. - -@item C-c ] -Close the current block on a separate line (@code{octave-close-block}). -An error is signaled if no block to close is found. - -@item C-c f -Insert a function skeleton, prompting for the function's name, arguments -and return values which have to be entered without parentheses -(@code{octave-insert-defun}). - -@item C-c C-h -Search the function, operator and variable indices of all info files -with documentation for Octave for entries (@code{octave-help}). If used -interactively, the entry is prompted for with completion. If multiple -matches are found, one can cycle through them using the standard -@samp{,} (@code{Info-index-next}) command of the Info reader. - -The variable @code{octave-help-files} is a list of files to search -through and defaults to @code{'("octave")}. If there is also an Octave -Local Guide with corresponding info file, say, @file{octave-LG}, you can -have @code{octave-help} search both files by -@lisp -(setq octave-help-files '("octave" "octave-LG")) -@end lisp -@noindent -in one of your Emacs startup files. - -@end table - -A common problem is that the @key{RET} key does @emph{not} indent the -line to where the new text should go after inserting the newline. This -is because the standard Emacs convention is that @key{RET} (aka -@kbd{C-m}) just adds a newline, whereas @key{LFD} (aka @kbd{C-j}) adds a -newline and indents it. This is particularly inconvenient for users with -keyboards which do not have a special @key{LFD} key at all; in such -cases, it is typically more convenient to use @key{RET} as the @key{LFD} -key (rather than typing @kbd{C-j}). - -You can make @key{RET} do this by adding -@lisp -(define-key octave-mode-map "\C-m" - 'octave-reindent-then-newline-and-indent) -@end lisp -@noindent -to one of your Emacs startup files. Another, more generally applicable -solution is -@lisp -(defun RET-behaves-as-LFD () - (let ((x (key-binding "\C-j"))) - (local-set-key "\C-m" x))) -(add-hook 'octave-mode-hook 'RET-behaves-as-LFD) -@end lisp -@noindent -(this works for all modes by adding to the startup hooks, without having -to know the particular binding of @key{RET} in that mode!). Similar -considerations apply for using @key{M-RET} as @key{M-LFD}. As Barry -A. Warsaw @email{bwarsaw@@cnri.reston.va.us} says in the documentation for his -@code{cc-mode}, ``This is a very common question. @code{:-)} If you want -this to be the default behavior, don't lobby me, lobby RMS!'' - -The following variables can be used to customize Octave mode. - -@table @code -@item octave-auto-indent -Non-@code{nil} means auto-indent the current line after a semicolon or -space. Default is @code{nil}. - -@item octave-auto-newline -Non-@code{nil} means auto-insert a newline and indent after semicolons -are typed. The default value is @code{nil}. - -@item octave-blink-matching-block -Non-@code{nil} means show matching begin of block when inserting a space, -newline or @samp{;} after an else or end keyword. Default is @code{t}. -This is an extremely useful feature for automatically verifying that the -keywords match---if they don't, an error message is displayed. - -@item octave-block-offset -Extra indentation applied to statements in block structures. -Default is 2. - -@item octave-continuation-offset -Extra indentation applied to Octave continuation lines. -Default is 4. - -@item octave-continuation-string -String used for Octave continuation lines. -Normally @samp{\}. - -@item octave-mode-startup-message -If @code{t} (default), a startup message is displayed when Octave mode -is called. - -@end table - -If Font Lock mode is enabled, Octave mode will display -@itemize @bullet -@item -strings in @code{font-lock-string-face} - -@item -comments in @code{font-lock-comment-face} - -@item -the Octave reserved words (such as all block keywords) and the text -functions (such as @samp{cd} or @samp{who}) which are also reserved -using @code{font-lock-keyword-face} - -@item -the built-in operators (@samp{&&}, @samp{==}, @dots{}) using -@code{font-lock-reference-face} - -@item -and the function names in function declarations in -@code{font-lock-function-name-face}. -@end itemize - -There is also rudimentary support for Imenu (currently, function names -can be indexed). - -Customization of Octave mode can be performed by modification of the -variable @code{octave-mode-hook}. It the value of this variable is -non-@code{nil}, turning on Octave mode calls its value. - -If you discover a problem with Octave mode, you can conveniently send a -bug report using @kbd{C-c C-b} (@code{octave-submit-bug-report}). This -automatically sets up a mail buffer with version information already -added. You just need to add a description of the problem, including a -reproducible test case and send the message. - -@node Running Octave From Within Emacs -@section Running Octave From Within Emacs - -The package @file{octave} provides commands for running an inferior -Octave process in a special Emacs buffer. Use -@lisp -M-x run-octave -@end lisp -@noindent -to directly start an inferior Octave process. If Emacs does not know -about this command, add the line -@lisp -(autoload 'run-octave "octave-inf" nil t) -@end lisp -@noindent -to your @file{.emacs} file. - -This will start Octave in a special buffer the name of which is -specified by the variable @code{inferior-octave-buffer} and defaults to -@code{"*Inferior Octave*"}. From within this buffer, you can -interact with the inferior Octave process `as usual', i.e., by entering -Octave commands at the prompt. The buffer is in Inferior Octave mode, -which is derived from the standard Comint mode, a major mode for -interacting with an inferior interpreter. See the documentation for -@code{comint-mode} for more details, and use @kbd{C-h b} to find out -about available special keybindings. - -You can also communicate with an inferior Octave process from within -files with Octave code (i.e., buffers in Octave mode), using the -following commands. - -@table @kbd -@item C-c i l -Send the current line to the inferior Octave process -(@code{octave-send-line}). -With positive prefix argument @var{N}, send that many lines. -If @code{octave-send-line-auto-forward} is non-@code{nil}, go to the -next unsent code line. - -@item C-c i b -Send the current block to the inferior Octave process -(@code{octave-send-block}). - -@item C-c i f -Send the current function to the inferior Octave process -(@code{octave-send-defun}). - -@item C-c i r -Send the region to the inferior Octave process -(@code{octave-send-region}). - -@item C-c i s -Make sure that `inferior-octave-buffer' is displayed -(@code{octave-show-process-buffer}). - -@item C-c i h -Delete all windows that display the inferior Octave buffer -(@code{octave-hide-process-buffer}). - -@item C-c i k -Kill the inferior Octave process and its buffer -(@code{octave-kill-process}). -@end table - -The effect of the commands which send code to the Octave process can be -customized by the following variables. -@table @code -@item octave-send-echo-input -Non-@code{nil} means echo input sent to the inferior Octave process. -Default is @code{t}. - -@item octave-send-show-buffer -Non-@code{nil} means display the buffer running the Octave process after -sending a command (but without selecting it). -Default is @code{t}. -@end table - -If you send code and there is no inferior Octave process yet, it will be -started automatically. - -The startup of the inferior Octave process is highly customizable. -The variable @code{inferior-octave-startup-args} can be used for -specifying command lines arguments to be passed to Octave on startup -as a list of strings. For example, to suppress the startup message and -use `traditional' mode, set this to @code{'("-q" "--traditional")}. -You can also specify a startup file of Octave commands to be loaded on -startup; note that these commands will not produce any visible output -in the process buffer. Which file to use is controlled by the variable -@code{inferior-octave-startup-file}. If this is @code{nil}, the file -@file{~/.emacs-octave} is used if it exists. - -And finally, @code{inferior-octave-mode-hook} is run after starting the -process and putting its buffer into Inferior Octave mode. Hence, if you -like the up and down arrow keys to behave in the interaction buffer as -in the shell, and you want this buffer to use nice colors, add -@lisp -(add-hook 'inferior-octave-mode-hook - (lambda () - (turn-on-font-lock) - (define-key inferior-octave-mode-map [up] - 'comint-previous-input) - (define-key inferior-octave-mode-map [down] - 'comint-next-input))) -@end lisp -@noindent -to your @file{.emacs} file. You could also swap the roles of @kbd{C-a} -(@code{beginning-of-line}) and @code{C-c C-a} (@code{comint-bol}) using -this hook. - -@quotation -@strong{Note:} -If you set your Octave prompts to something different from the defaults, -make sure that @code{inferior-octave-prompt} matches them. -Otherwise, @emph{nothing} will work, because Emacs will have no idea -when Octave is waiting for input, or done sending output. -@end quotation - -@node Using the Emacs Info Reader for Octave -@section Using the Emacs Info Reader for Octave - -You can also set up the Emacs Info reader for dealing with the results -of Octave's @samp{help -i}. For this, the package @file{gnuserv} needs -to be installed, which unfortunately still does not come with GNU Emacs -(it does with XEmacs). It can be retrieved from any GNU Emacs Lisp Code -Directory archive, e.g.@: -@url{ftp://ftp.cis.ohio-state.edu/pub/gnu/emacs/elisp-archive}, -in the @file{packages} subdirectory. The alpha version of an enhanced -version of gnuserv is available at -@url{ftp://ftp.wellfleet.com/netman/psmith/emacs/gnuserv-2.1alpha.tar.gz}. - -If @file{gnuserv} is installed, add the lines -@lisp -(autoload 'octave-help "octave-hlp" nil t) -(require 'gnuserv) -(gnuserv-start) -@end lisp -@noindent -to your @file{.emacs} file. - -You can use either `plain' Emacs Info or the function @code{octave-help} -as your Octave info reader (for @samp{help -i}). In the former case, -set the Octave variable @w{@env{INFO_PROGRAM}} to @code{"info-emacs-info"}. -The latter is perhaps more attractive because it allows to look up keys -in the indices of @emph{several} info files related to Octave (provided -that the Emacs variable @code{octave-help-files} is set correctly). In -this case, set @w{@env{INFO_PROGRAM}} to @code{"info-emacs-octave-help"}. - -If you use Octave from within Emacs, these settings are best done in the -@file{~/.emacs-octave} startup file (or the file pointed to by the Emacs -variable @code{inferior-octave-startup-file}).
--- a/doc/interpreter/expr.txi Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/interpreter/expr.txi Fri Aug 12 14:16:34 2011 -0400 @@ -1239,51 +1239,62 @@ any such mistake. When operators of equal precedence are used together, the leftmost -operator groups first, except for the assignment and exponentiation -operators, which group in the opposite order. Thus, the expression -@code{a - b + c} groups as @code{(a - b) + c}, but the expression -@code{a = b = c} groups as @code{a = (b = c)}. +operator groups first, except for the assignment operators, which group +in the opposite order. Thus, the expression @code{a - b + c} groups as +@code{(a - b) + c}, but the expression @code{a = b = c} groups as +@code{a = (b = c)}. The precedence of prefix unary operators is important when another operator follows the operand. For example, @code{-x^2} means @code{-(x^2)}, because @samp{-} has lower precedence than @samp{^}. -Here is a table of the operators in Octave, in order of increasing -precedence. +Here is a table of the operators in Octave, in order of decreasing +precedence. Unless noted, all operators group left to right. @table @code -@item statement separators -@samp{;}, @samp{,}. +@item function call and array indexing, cell array indexing, and structure element indexing +@samp{()} @samp{@{@}} @samp{.} + +@item postfix increment, and postfix decrement +@samp{++} @samp{--} + +These operators group right to left. + +@item transpose and exponentiation +@samp{'} @samp{.'} @samp{^} @samp{**} @samp{.^} @samp{.**} -@item assignment -@samp{=}, @samp{+=}, @samp{-=}, @samp{*=},@samp{/=}. This operator -groups right to left. +@item unary plus, unary minus, prefix increment, prefix decrement, and logical "not" +@samp{+} @samp{-} @samp{++} @samp{--} @samp{~} @samp{!} + +@item multiply and divide +@samp{*} @samp{/} @samp{\} @samp{.\} @samp{.*} @samp{./} -@item logical "or" and "and" -@samp{||}, @samp{&&}. +@item add, subtract +@samp{+} @samp{-} -@item element-wise "or" and "and" -@samp{|}, @samp{&}. +@item colon +@samp{:} @item relational -@samp{<}, @samp{<=}, @samp{==}, @samp{>=}, @samp{>}, @samp{!=}, -@samp{~=}. +@samp{<} @samp{<=} @samp{==} @samp{>=} @samp{>} @samp{!=} +@samp{~=} -@item colon -@samp{:}. +@item element-wise "and" +@samp{&} -@item add, subtract -@samp{+}, @samp{-}. +@item element-wise "or" +@samp{|} -@item multiply, divide -@samp{*}, @samp{/}, @samp{\}, @samp{.\}, @samp{.*}, @samp{./}. +@item logical "and" +@samp{&&} -@item transpose -@samp{'}, @samp{.'} +@item logical "or" +@samp{||} -@item unary plus, minus, increment, decrement, and ``not'' -@samp{+}, @samp{-}, @samp{++}, @samp{--}, @samp{!}, @samp{~}. +@item assignment +@samp{=} @samp{+=} @samp{-=} @samp{*=} @samp{/=} @samp{\=} +@samp{^=} @samp{.*=} @samp{./=} @samp{.\=} @samp{.^=} @samp{|=} +@samp{&=} -@item exponentiation -@samp{^}, @samp{**}, @samp{.^}, @samp{.**}. +These operators group right to left. @end table
--- a/doc/interpreter/matrix.txi Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/interpreter/matrix.txi Fri Aug 12 14:16:34 2011 -0400 @@ -254,8 +254,6 @@ @DOCSTRING(rosser) -@DOCSTRING(sylvester_matrix) - @DOCSTRING(toeplitz) @DOCSTRING(vander)
--- a/doc/interpreter/plot.txi Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/interpreter/plot.txi Fri Aug 12 14:16:34 2011 -0400 @@ -2396,7 +2396,11 @@ may override the factory defaults. Although default values may be set for any object, they are set in -parent objects and apply to child objects. For example, +parent objects and apply to child objects, of the specified object type. +For example, seeting the default @code{color} property of @code{line} +objects to "green", for the @code{root} object, will result in all +@code{line} objects inheriting the @code{color} "green" as the default +value. @example set (0, "defaultlinecolor", "green");
--- a/doc/interpreter/stats.txi Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/interpreter/stats.txi Fri Aug 12 14:16:34 2011 -0400 @@ -114,7 +114,7 @@ @DOCSTRING(center) -@DOCSTRING(studentize) +@DOCSTRING(zscore) @DOCSTRING(histc) @@ -168,9 +168,7 @@ @DOCSTRING(cov) -@DOCSTRING(cor) - -@DOCSTRING(corrcoef) +@DOCSTRING(corr) @DOCSTRING(spearman)
--- a/doc/refcard/refcard.tex Fri Aug 12 14:05:48 2011 -0400 +++ b/doc/refcard/refcard.tex Fri Aug 12 14:16:34 2011 -0400 @@ -863,14 +863,14 @@ gray2ind ({\it i}, {\it n})&convert gray scale to Octave image\cr image ({\it img}, {\it zoom})&display an Octave image matrix\cr imagesc ({\it img}, {\it zoom})&display scaled matrix as image\cr +imread ({\it file})&load an image file\cr imshow ({\it img}, {\it map})&display Octave image\cr imshow ({\it i}, {\it n})&display gray scale image\cr imshow ({\it r}, {\it g}, {\it b})&display RGB image\cr +imwrite ({\it img}, {\it file})&write images in various file formats\cr ind2gray ({\it img}, {\it map})&convert Octave image to gray scale\cr ind2rgb ({\it img}, {\it map})&convert indexed image to RGB\cr -loadimage ({\it file})&load an image file\cr rgb2ind ({\it r}, {\it g}, {\it b})&convert RGB to Octave image\cr -\omit\tt saveimage ({\it file}, {\it img}, {\it fmt}, {\it map})\quad\rm save a matrix to {\it file}\span\cr \endsec
--- a/etc/OLD-ChangeLogs/ChangeLog Fri Aug 12 14:05:48 2011 -0400 +++ b/etc/OLD-ChangeLogs/ChangeLog Fri Aug 12 14:16:34 2011 -0400 @@ -2,6 +2,10 @@ * NEWS: Add colstyle to list of new functions for 3.4 +2011-04-08 Rik <octave@nomad.inbox5.com> + + * NEWS: Deprecate studentize(), add new function zscore(). + 2011-04-04 Rik <octave@nomad.inbox5.com> * NEWS: Add perror, strerror to list of functions deprecated in 3.4 @@ -88,6 +92,11 @@ * NEWS: Use indentation of 2 spaces rather than 3 in code examples. +2011-02-08 John W. Eaton <jwe@octave.org> + + * NEWS: New section for 3.6. List deprecated functions that + have been removed for 3.6. + 2011-02-08 Ben Abbott <bpabbott@mac.com> * README.MacOS: Add detail.
--- a/etc/OLD-ChangeLogs/doc-ChangeLog Fri Aug 12 14:05:48 2011 -0400 +++ b/etc/OLD-ChangeLogs/doc-ChangeLog Fri Aug 12 14:16:34 2011 -0400 @@ -1,3 +1,7 @@ +2011-04-16 Ben Abbott <bpabbott@mac.com> + + * interpreter/plot.txi: Clarify that inheritance of default property + values only applies to the named object type. 2011-04-14 Rik <octave@nomad.inbox5.com> * interpreter/plot.txi: Add colstyle function to documentation. @@ -16,6 +20,11 @@ * interpreter/func.txi: Add discussion of isargout to Ignoring Arguments section of documentation. +2011-04-08 Rik <octave@nomad.inbox5.com> + + * interpreter/stats.txi: Deprecate studentize(), replace with + zscore(). + 2011-04-07 Rik <octave@nomad.inbox5.com> * interpreter/Makefile.am: Add spellcheck target to documentation @@ -42,7 +51,7 @@ 2011-04-04 Rik <octave@nomad.inbox5.com> - * interpreter/doccheck/aspell-octave.en.pws, interpreter/nonlin.txi, + * interpreter/doccheck/aspell-octave.en.pws, interpreter/nonlin.txi, interpreter/tips.txi: Spellcheck documentation for 3.4.1 release. 2011-04-04 Rik <octave@nomad.inbox5.com>
--- a/etc/OLD-ChangeLogs/liboctave-ChangeLog Fri Aug 12 14:05:48 2011 -0400 +++ b/etc/OLD-ChangeLogs/liboctave-ChangeLog Fri Aug 12 14:16:34 2011 -0400 @@ -1,3 +1,7 @@ +2011-04-12 Rik <octave@nomad.inbox5.com> + + * LSODE.cc: Add semicolon to error messages to prevent run-together text. + 2011-04-01 Jordi Gutiérrez Hermoso <jordigh@gmail.com> * MatrixType (MatrixType::operator =): Plug memory leak due to
--- a/etc/OLD-ChangeLogs/scripts-ChangeLog Fri Aug 12 14:05:48 2011 -0400 +++ b/etc/OLD-ChangeLogs/scripts-ChangeLog Fri Aug 12 14:16:34 2011 -0400 @@ -1,8 +1,47 @@ +2011-04-18 Paul Boven <p.boven@xs4all.nl> + + * image/image.m: Fixed naming of variables in texinfo + +2011-04-17 Patrick Häcker <magicmuscleman> + + * strings/mat2str.m: Limit the number of digits to one less than + available for double. + +2011-04-15 Kai Habel <kai.habel@gmx.de> + + * general/interp1.m, polynomial/mkpp.m, polynomial/pchip.m, + polynomial/ppder.m, polynomial/ppint.m, polynomial/ppjumps.m, + polynomial/ppval.m, polynomial/spline.m, polynomial/unmkpp.m: + Make functions more compatible with respect to handling of + picewise polynoms (pp). Rename pp-struct elements. + Handle nD-arguments correctly. Tests added. + (bugs #32040, #32045) + 2011-04-13 David Bateman <dbateman@free.fr> * plot/colstyle.m : New function. * plot/module.mk plot_FCN_FILES) : Add it here. +2011-04-13 Rik <octave@nomad.inbox5.com> + + * help/__makeinfo__.m: Simplify function by using regular expressions. + Eliminate third input argument see_also function. + +2011-04-13 Rik <octave@nomad.inbox5.com> + + * general/isdir.m, general/isequal.m, general/isequalwithequalnans.m, + general/isscalar.m, general/issquare.m, general/isvector.m: Refactor + code to put input validation first. + + * general/iscolumn.m, general/isrow.m : Remove useless initialization + of output variable. + + * general/isa.m: Add additional tests for various classes. + +2011-04-13 Rik <octave@nomad.inbox5.com> + + * ChangeLog: Remove results of bad merge in ChangeLog. + 2011-04-12 Ben Abbott <bpabbott@mac.com> * miscellaneous/getappdata.m: If no property name is provided, return @@ -20,10 +59,21 @@ 2011-04-08 Rik <octave@nomad.inbox5.com> + * deprecated/module.mk, statistics/base/center.m, + statistics/base/module.mk: Deprecate studentize(), replace with + zscore(). + +2011-04-08 Rik <octave@nomad.inbox5.com> + * linear-algebra/cond.m, linear-algebra/expm.m, linear-algebra/logm.m, linear-algebra/null.m, linear-algebra/orth.m, linear-algebra/rank.m, linear-algebra/rref.m: Improve docstrings. +2011-04-08 Rik <octave@nomad.inbox5.com> + + * statistics/base/mode.m, statistics/base/quantile.m: Return output + of same class as input. + 2011-04-06 Rik <octave@nomad.inbox5.com> * miscellaneous/pack.m: Improve docstring. @@ -397,6 +447,25 @@ * plot/__go_draw_axes__.m: Properly set fontspec for legends. +2011-02-08 John W. Eaton <jwe@octave.org> + + * deprecated/complement.m, deprecated/create_set.m, + deprecated/dmult.m, deprecated/iscommand.m, + deprecated/israwcommand.m, deprecated/lchol.m, + deprecated/loadimage.m, deprecated/mark_as_command.m, + deprecated/mark_as_rawcommand.m, deprecated/spatan2.m, + deprecated/spchol2inv.m, deprecated/spcholinv.m, + deprecated/spchol.m, deprecated/spcumprod.m, + deprecated/spcumsum.m, deprecated/spdet.m, deprecated/spdiag.m, + deprecated/spfind.m, deprecated/spinv.m, deprecated/spkron.m, + deprecated/splchol.m, deprecated/split.m, deprecated/splu.m, + deprecated/spmax.m, deprecated/spmin.m, deprecated/spprod.m, + deprecated/spqr.m, deprecated/spsum.m, deprecated/spsumsq.m, + deprecated/str2mat.m, deprecated/unmark_command.m, + deprecated/unmark_rawcommand.m: + Remove functions deprecated in version 3.2. + * module.mk (deprecated_FCN_FILES): Remove them from the list. + 2011-02-05 David Bateman <dbateman@free.fr> * plot/legend.m: Allow the location and orientation to be set
--- a/etc/OLD-ChangeLogs/src-ChangeLog Fri Aug 12 14:05:48 2011 -0400 +++ b/etc/OLD-ChangeLogs/src-ChangeLog Fri Aug 12 14:16:34 2011 -0400 @@ -1,10 +1,15 @@ +2011-04-19 Kai Habel <kai.habel@gmx.de> + + * src/DLD-FUNCTIONS/__init_fltk__.cc(plot_window::plot_window): + Instantiate canvas before uimenu. + 2011-04-13 Rik <octave@nomad.inbox5.com> * help.cc: Add spaces after commas in @seealso blocks. 2011-04-12 Rik <octave@nomad.inbox5.com> - * load-path.cc (restoredefaultpath): Correct use of it's -> its in + * load-path.cc (restoredefaultpath): Correct use of it's -> its in documentation. 2011-04-10 John Eaton <jwe@octave.org> @@ -90,7 +95,7 @@ * DLD-FUNCTIONS/inv.cc (inv, inverse), DLD-FUNCTIONS/tril.cc (tril), data.cc (cumsum, szie), file-io.cc (fgets), ov-typeinfo.cc (typeinfo), - ov-usr-fcn.cc (nargout), utils.cc (make_absolute_filename), + ov-usr-fcn.cc (nargout), utils.cc (make_absolute_filename), variables.cc (who): Improve docstrings 2011-03-25 John W. Eaton <jwe@octave.org> @@ -342,6 +347,10 @@ 2011-02-08 John W. Eaton <jwe@octave.org> + * DLD-FUNCTIONS/chol.cc: Delete obsolete test of spcholinv. + +2011-02-08 John W. Eaton <jwe@octave.org> + * oct-parse.yy (parse_fcn_file): Don't warn about coercing nested functions to subfunctions if yyparse failed.
--- a/etc/OLD-ChangeLogs/test-ChangeLog Fri Aug 12 14:05:48 2011 -0400 +++ b/etc/OLD-ChangeLogs/test-ChangeLog Fri Aug 12 14:16:34 2011 -0400 @@ -1,3 +1,9 @@ +2011-04-11 Rik <octave@nomad.inbox5.com> + + * fntests.m: Remove deprecated and private functions from list of + functions requiring tests. Count functions with %!demo blocks as + having tests. + 2011-04-03 Rik <octave@nomad.inbox5.com> * test_diag_perm.m: Reverse previous changeset. Return 3-input form
--- a/liboctave/LSODE.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/liboctave/LSODE.cc Fri Aug 12 14:16:34 2011 -0400 @@ -292,7 +292,7 @@ case -2: // excess accuracy requested (tolerances too small). case -3: // invalid input detected (see printed message). case -4: // repeated error test failures (check all inputs). - case -5: // repeated convergence failures (perhaps bad jacobian + case -5: // repeated convergence failures (perhaps bad Jacobian // supplied or wrong choice of mf or tolerances). case -6: // error weight became zero during problem. (solution // component i vanished, and atol or atol(i) = 0.) @@ -349,13 +349,13 @@ case -4: retval = std::string ("repeated error test failures (t = ") - + t_curr + "check all inputs)"; + + t_curr + "; check all inputs)"; break; case -5: retval = std::string ("repeated convergence failures (t = ") + t_curr - + "perhaps bad jacobian supplied or wrong choice of integration method or tolerances)"; + + "; perhaps bad Jacobian supplied or wrong choice of integration method or tolerances)"; break; case -6:
--- a/liboctave/lo-utils.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/liboctave/lo-utils.cc Fri Aug 12 14:16:34 2011 -0400 @@ -244,6 +244,8 @@ return d; } +// Read a double value. Discard any sign on NaN and NA. + template <> double octave_read_value (std::istream& is) @@ -261,7 +263,7 @@ { char c2 = 0; c2 = is.get (); - if (c2 == 'i' || c2 == 'I') + if (c2 == 'i' || c2 == 'I' || c2 == 'n' || c2 == 'N') d = read_inf_nan_na (is, c2, c1); else { @@ -276,7 +278,7 @@ { char c2 = 0; c2 = is.get (); - if (c2 == 'i' || c2 == 'I') + if (c2 == 'i' || c2 == 'I' || c2 == 'n' || c2 == 'N') d = read_inf_nan_na (is, c2, c1); else { @@ -392,6 +394,8 @@ return d; } +// Read a float value. Discard any sign on NaN and NA. + template <> float octave_read_value (std::istream& is) @@ -409,7 +413,7 @@ { char c2 = 0; c2 = is.get (); - if (c2 == 'i' || c2 == 'I') + if (c2 == 'i' || c2 == 'I' || c2 == 'n' || c2 == 'N') d = read_float_inf_nan_na (is, c2, c1); else { @@ -424,7 +428,7 @@ { char c2 = 0; c2 = is.get (); - if (c2 == 'i' || c2 == 'I') + if (c2 == 'i' || c2 == 'I' || c2 == 'n' || c2 == 'N') d = read_float_inf_nan_na (is, c2, c1); else {
--- a/scripts/audio/playaudio.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/audio/playaudio.m Fri Aug 12 14:16:34 2011 -0400 @@ -47,7 +47,10 @@ num = fopen (file, "wb"); c = fwrite (num, X, "uchar"); fclose (num); - system (sprintf ("cat \"%s\" > /dev/dsp", file)); + [status, out] = system (sprintf ("cat \"%s\" > /dev/dsp", file)); + if (status != 0) + system (sprintf ("paplay --raw \"%s\"", file)) + endif unwind_protect_cleanup unlink (file); end_unwind_protect @@ -61,10 +64,16 @@ print_usage (); endif if (strcmp (ext, "lin") || strcmp (ext, "raw")) - system (sprintf ("cat \"%s\" > /dev/dsp", name)); + [status, out] = system (sprintf ("cat \"%s\" > /dev/dsp", name)); + if (status != 0) + system (sprintf ("paplay --raw \"%s\"", name)) + endif elseif (strcmp (ext, "mu") || strcmp (ext, "au") || strcmp (ext, "snd") || strcmp (ext, "ul")) - system (sprintf ("cat \"%s\" > /dev/audio", name)); + [status, out] = system (sprintf ("cat \"%s\" > /dev/audio", name)); + if (status != 0) + system (sprintf ("paplay \"%s\"", name)) + endif else error ("playaudio: unsupported extension"); endif
--- a/scripts/audio/wavread.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/audio/wavread.m Fri Aug 12 14:16:34 2011 -0400 @@ -240,7 +240,6 @@ endif endfunction - -%% Tests for wavread/wavwrite pair are in wavrite.m -%!assert(1) # stop fntests.m from reporting no tests for wavread - +## Mark file as being tested. Tests for wavread/wavwrite pair are in +## wavwrite.m +%!assert(1)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/__error_text__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,36 @@ +## Copyright (C) 2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} __error_text__ (@var{msg}, @var{msgid}) +## This function has been deprecated. Use @code{lasterr} instead. +## @seealso{lasterr} +## @end deftypefn + +function [msg, msgid] = __error_text__ (varargin) + + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "__error_text__ is obsolete and will be removed from a future version of Octave, please use lasterr instead"); + endif + + [msg, msgid] = lasterr (varargin{:}); + +endfunction
--- a/scripts/deprecated/complement.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,78 +0,0 @@ -## Copyright (C) 1994-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} complement (@var{x}, @var{y}) -## Return the elements of set @var{y} that are not in set @var{x}. For -## example: -## -## @example -## @group -## complement ([ 1, 2, 3 ], [ 2, 3, 5 ]) -## @result{} 5 -## @end group -## @end example -## @seealso{union, intersect, unique} -## @end deftypefn - -## Author: jwe - -## Deprecated in version 3.2 - -function y = complement (a, b) - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "complement is obsolete and will be removed from a future version of Octave, please use setdiff instead"); - endif - - if (nargin != 2) - print_usage (); - endif - - if (isempty (a)) - y = unique (b); - elseif (isempty (b)) - y = []; - else - a = unique (a); - b = unique (b); - yindex = 1; - y = zeros (1, length (b)); - for index = 1:length (b) - if (all (a != b (index))) - y(yindex++) = b(index); - endif - endfor - y = y(1:(yindex-1)); - endif - -endfunction - -%!assert(all (all (complement ([1, 2, 3], [3; 4; 5; 6]) == [4, 5, 6]))); - -%!assert(all (all (complement ([1, 2, 3], [3, 4, 5, 6]) == [4, 5, 6]))); - -%!assert(isempty (complement ([1, 2, 3], [3, 2, 1]))); - -%!error complement (1); - -%!error complement (1, 2, 3); -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/cor.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,54 @@ +## Copyright (C) 1995-2011 Kurt Hornik +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} cor (@var{x}) +## @deftypefnx {Function File} {} cor (@var{x}, @var{y}) +## Compute matrix of correlation coefficients. +## +## This is an alias for @code{corrcoef}. +## @seealso{corrcoef} +## @end deftypefn + +function retval = cor (x, y = x) + + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "cor is obsolete and will be removed from a future version of Octave; please use corr instead"); + endif + + if (nargin < 1 || nargin > 2) + print_usage (); + endif + + retval = corrcoef (x, y); + +endfunction + + +%!test +%! x = rand (10, 2); +%! assert (cor (x), corrcoef (x), 5*eps); +%! assert (cor (x(:,1), x(:,2)) == corrcoef (x(:,1), x(:,2))); + +%% Test input validation +%!error corrcoef (); +%!error corrcoef (1, 2, 3); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/corrcoef.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,119 @@ +## Copyright (C) 1996-2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} corrcoef (@var{x}) +## @deftypefnx {Function File} {} corrcoef (@var{x}, @var{y}) +## Compute matrix of correlation coefficients. +## +## If each row of @var{x} and @var{y} is an observation and each column is +## a variable, then the @w{(@var{i}, @var{j})-th} entry of +## @code{corrcoef (@var{x}, @var{y})} is the correlation between the +## @var{i}-th variable in @var{x} and the @var{j}-th variable in @var{y}. +## @tex +## $$ +## {\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)} +## $$ +## @end tex +## @ifnottex +## +## @example +## corrcoef(x,y) = cov(x,y)/(std(x)*std(y)) +## @end example +## +## @end ifnottex +## If called with one argument, compute @code{corrcoef (@var{x}, @var{x})}, +## the correlation between the columns of @var{x}. +## @seealso{cov} +## @end deftypefn + +## Author: Kurt Hornik <hornik@wu-wien.ac.at> +## Created: March 1993 +## Adapted-By: jwe + +function retval = corrcoef (x, y = []) + + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "corrcoef is not equivalent to Matlab and will be removed from a future version of Octave; for similar functionality see corr"); + endif + + if (nargin < 1 || nargin > 2) + print_usage (); + endif + + ## Input validation is done by cov.m. Don't repeat tests here + + ## Special case, scalar is always 100% correlated with itself + if (isscalar (x)) + if (isa (x, 'single')) + retval = single (1); + else + retval = 1; + endif + return; + endif + + ## No check for division by zero error, which happens only when + ## there is a constant vector and should be rare. + if (nargin == 2) + c = cov (x, y); + s = std (x)' * std (y); + retval = c ./ s; + else + c = cov (x); + s = sqrt (diag (c)); + retval = c ./ (s * s'); + endif + +endfunction + + +%!test +%! x = rand (10); +%! cc1 = corrcoef (x); +%! cc2 = corrcoef (x, x); +%! assert (size (cc1) == [10, 10] && size (cc2) == [10, 10]); +%! assert (cc1, cc2, sqrt (eps)); + +%!test +%! x = [1:3]'; +%! y = [3:-1:1]'; +%! assert (corrcoef (x,y), -1, 5*eps) +%! assert (corrcoef (x,flipud (y)), 1, 5*eps) +%! assert (corrcoef ([x, y]), [1 -1; -1 1], 5*eps) + +%!test +%! x = single ([1:3]'); +%! y = single ([3:-1:1]'); +%! assert (corrcoef (x,y), single (-1), 5*eps) +%! assert (corrcoef (x,flipud (y)), single (1), 5*eps) +%! assert (corrcoef ([x, y]), single ([1 -1; -1 1]), 5*eps) + +%!assert (corrcoef (5), 1); +%!assert (corrcoef (single(5)), single(1)); + +%% Test input validation +%!error corrcoef (); +%!error corrcoef (1, 2, 3); +%!error corrcoef ([1; 2], ["A", "B"]); +%!error corrcoef (ones (2,2,2)); +%!error corrcoef (ones (2,2), ones (2,2,2)); +
--- a/scripts/deprecated/create_set.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,79 +0,0 @@ -## Copyright (C) 1994-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} create_set (@var{x}) -## @deftypefnx {Function File} {} create_set (@var{x}, "rows") -## This function has been deprecated. Use unique instead. -## @end deftypefn - -## Return a row vector containing the unique values in @var{x}, sorted in -## ascending order. For example, -## -## @example -## @group -## create_set ([ 1, 2; 3, 4; 4, 2; 1, 2 ]) -## @result{} [ 1, 2, 3, 4 ] -## @end group -## @end example -## -## If the optional second input argument is the string "rows" each row of -## the matrix @var{x} will be considered an element of set. For example, -## @example -## @group -## create_set ([ 1, 2; 3, 4; 4, 2; 1, 2 ], "rows") -## @result{} 1 2 -## 3 4 -## 4 2 -## @end group -## @end example -## @seealso{union, intersect, complement, unique} - -## Author: jwe - -## Deprecated in version 3.2 - -function y = create_set (x, rows_opt) - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "create_set is obsolete and will be removed from a future version of Octave, please use unique instead"); - endif - - if (nargin < 1 || nargin > 2) - print_usage (); - endif - - if (nargin == 1) - y = unique (x)(:)'; - elseif (strcmpi (rows_opt, "rows")) - y = unique (x, "rows"); - else - error ("create_set: expecting \"rows\" as second argument"); - endif - -endfunction - -%!assert(all (all (create_set ([1, 2, 3, 4, 2, 4]) == [1, 2, 3, 4]))); -%!assert(all (all (create_set ([1, 2; 3, 4; 2, 4]) == [1, 2, 3, 4]))); -%!assert(all (all (create_set ([1; 2; 3; 4; 2; 4]) == [1, 2, 3, 4]))); -%!assert(isempty (create_set ([]))); -%!error create_set (1, 2); -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/cut.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,71 @@ +## Copyright (C) 1996-2011 Kurt Hornik +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} cut (@var{x}, @var{breaks}) +## Create categorical data from numerical or continuous data by +## cutting into intervals. +## +## If @var{breaks} is a scalar, the data is cut into that many +## equal-width intervals. If @var{breaks} is a vector of break points, +## the category has @code{length (@var{breaks}) - 1} groups. +## +## The returned value is a vector of the same size as @var{x} telling +## which group each point in @var{x} belongs to. Groups are labelled +## from 1 to the number of groups; points outside the range of +## @var{breaks} are labelled by @code{NaN}. +## @seealso{histc} +## @end deftypefn + +## Author: KH <Kurt.Hornik@wu-wien.ac.at> +## Description: Cut data into intervals + +function group = cut (x, breaks) + + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "cut is obsolete and will be removed from a future version of Octave; please use histc instead"); + endif + + if (nargin != 2) + print_usage (); + endif + + if (!isvector (x)) + error ("cut: X must be a vector"); + endif + if isscalar (breaks) + breaks = linspace (min (x), max (x), breaks + 1); + breaks(1) = breaks(1) - 1; + elseif isvector (breaks) + breaks = sort (breaks); + else + error ("cut: BREAKS must be a scalar or vector"); + endif + + group = NaN (size (x)); + m = length (breaks); + if any (k = find ((x >= min (breaks)) & (x < max (breaks)))) + n = length (k); + group(k) = sum ((ones (m, 1) * reshape (x(k), 1, n)) + >= (reshape (breaks, m, 1) * ones (1, n))); + endif + +endfunction
--- a/scripts/deprecated/dmult.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -## Copyright (C) 1995-2011 Kurt Hornik -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} dmult (@var{a}, @var{b}) -## This function has been deprecated. Use the direct syntax @code{diag(A)*B} -## which is more readable and now also more efficient. -## @end deftypefn - -## Author: KH <Kurt.Hornik@wu-wien.ac.at> -## Description: Rescale the rows of a matrix - -## Deprecated in version 3.2 - -function M = dmult (a, B) - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "dmult is obsolete and will be removed from a future version of Octave; please use the straightforward (and now efficient) syntax \"diag(A)*B\""); - endif - - if (nargin != 2) - print_usage (); - endif - if (! isvector (a)) - error ("dmult: a must be a vector of length rows (B)"); - endif - a = a(:); - sb = size (B); - sb(1) = 1; - M = repmat (a(:), sb) .* B; -endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/error_text.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,36 @@ +## Copyright (C) 2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} error_text (@var{msg}, @var{msgid}) +## This function has been deprecated. Use @code{lasterr} instead. +## @seealso{lasterr} +## @end deftypefn + +function [msg, msgid] = error_text (varargin) + + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "error_text is obsolete and will be removed from a future version of Octave, please use lasterr instead"); + endif + + [msg, msgid] = lasterr (varargin{:}); + +endfunction
--- a/scripts/deprecated/iscommand.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -## Copyright (C) 2009-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Built-in Function} {} iscommand (@var{name}) -## This function is obsolete and will be removed from a future -## version of Octave. -## @end deftypefn - -## Author: jwe - -## Deprecated in version 3.2 - -function retval = iscommand () - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "iscommand is obsolete and will be removed from a future version of Octave"); - endif - - if (nargin == 0) - retval = {}; - else - retval = true; - endif - -endfunction
--- a/scripts/deprecated/israwcommand.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -## Copyright (C) 2009-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Built-in Function} {} israwcommand (@var{name}) -## This function is obsolete and will be removed from a future -## version of Octave. -## @end deftypefn - -## Author: jwe - -## Deprecated in version 3.2 - -function retval = israwcommand () - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "israwcommand is obsolete and will be removed from a future version of Octave"); - endif - - if (nargin == 0) - retval = {}; - else - retval = true; - endif - -endfunction
--- a/scripts/deprecated/lchol.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Loadable Function} {@var{l} =} lchol (@var{a}) -## @deftypefnx {Loadable Function} {[@var{l}, @var{p}] =} lchol (@var{a}) -## This function has been deprecated. Use @code{chol (@dots{},'lower')} -## instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = lchol (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spfind is obsolete and will be removed from a future version of Octave; please use find instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = chol (varargin{:}, "lower"); - -endfunction
--- a/scripts/deprecated/loadimage.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,43 +0,0 @@ -## Copyright (C) 1994-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{x}, @var{map}] =} loadimage (@var{file}) -## Load an image file and its associated color map from the specified -## @var{file}. The image must be stored in Octave's image format. -## @seealso{saveimage, load, save} -## @end deftypefn - -## Author: Tony Richardson <arichard@stark.cc.oh.us> -## Created: July 1994 -## Adapted-By: jwe - -## Deprecated in version 3.2 - -function [img_retval, map_retval] = loadimage (varargin) - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "loadimage is obsolete and will be removed from a future version of Octave; please use imread instead"); - endif - - [img_retval, map_retval] = imread (varargin{:}); - -endfunction
--- a/scripts/deprecated/mark_as_command.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -## Copyright (C) 2009-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Built-in Function} {} mark_as_command (@var{name}) -## This function is obsolete and will be removed from a future -## version of Octave. -## @end deftypefn - -## Author: jwe - -## Deprecated in version 3.2 - -function mark_as_command () - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "mark_as_command is obsolete and will be removed from a future version of Octave"); - endif - -endfunction
--- a/scripts/deprecated/mark_as_rawcommand.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -## Copyright (C) 2009-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Built-in Function} {} mark_as_rawcommand (@var{name}) -## This function is obsolete and will be removed from a future -## version of Octave. -## @end deftypefn - -## Author: jwe - -## Deprecated in version 3.2 - -function mark_as_rawcommand () - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "mark_as_rawcommand is obsolete and will be removed from a future version of Octave"); - endif - -endfunction
--- a/scripts/deprecated/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/deprecated/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -6,55 +6,29 @@ deprecated/betai.m \ deprecated/cellidx.m \ deprecated/clg.m \ - deprecated/complement.m \ - deprecated/create_set.m \ + deprecated/cor.m \ + deprecated/corrcoef.m \ deprecated/cquad.m \ + deprecated/cut.m \ deprecated/dispatch.m \ - deprecated/dmult.m \ deprecated/fstat.m \ deprecated/gammai.m \ deprecated/glpkmex.m \ deprecated/intwarning.m \ - deprecated/iscommand.m \ deprecated/is_duplicate_entry.m \ deprecated/is_global.m \ - deprecated/israwcommand.m \ deprecated/isstr.m \ - deprecated/lchol.m \ - deprecated/loadimage.m \ deprecated/krylovb.m \ - deprecated/mark_as_command.m \ - deprecated/mark_as_rawcommand.m \ deprecated/perror.m \ + deprecated/polyderiv.m \ deprecated/replot.m \ deprecated/saveimage.m \ deprecated/setstr.m \ - deprecated/spatan2.m \ - deprecated/spchol2inv.m \ - deprecated/spcholinv.m \ - deprecated/spchol.m \ - deprecated/spcumprod.m \ - deprecated/spcumsum.m \ - deprecated/spdet.m \ - deprecated/spdiag.m \ - deprecated/spfind.m \ deprecated/sphcat.m \ - deprecated/spinv.m \ - deprecated/spkron.m \ - deprecated/splchol.m \ - deprecated/split.m \ - deprecated/splu.m \ - deprecated/spmax.m \ - deprecated/spmin.m \ - deprecated/spprod.m \ - deprecated/spqr.m \ - deprecated/spsum.m \ - deprecated/spsumsq.m \ deprecated/spvcat.m \ - deprecated/str2mat.m \ deprecated/strerror.m \ - deprecated/unmark_command.m \ - deprecated/unmark_rawcommand.m \ + deprecated/studentize.m \ + deprecated/sylvester_matrix.m \ deprecated/values.m \ deprecated/weibcdf.m \ deprecated/weibinv.m \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/polyderiv.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,108 @@ +## Copyright (C) 1994-2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} polyderiv (@var{p}) +## @deftypefnx {Function File} {[@var{k}] =} polyderiv (@var{a}, @var{b}) +## @deftypefnx {Function File} {[@var{q}, @var{d}] =} polyderiv (@var{b}, @var{a}) +## Return the coefficients of the derivative of the polynomial whose +## coefficients are given by the vector @var{p}. If a pair of polynomials +## is given, return the derivative of the product @math{@var{a}*@var{b}}. +## If two inputs and two outputs are given, return the derivative of the +## polynomial quotient @math{@var{b}/@var{a}}. The quotient numerator is +## in @var{q} and the denominator in @var{d}. +## @seealso{poly, polyint, polyreduce, roots, conv, deconv, residue, +## filter, polygcd, polyval, polyvalm} +## @end deftypefn + +## Author: Tony Richardson <arichard@stark.cc.oh.us> +## Created: June 1994 +## Adapted-By: jwe + +function [q, d] = polyderiv (p, a) + + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "polyderiv is obsolete and will be removed from a future version of Octave; please use polyder instead"); + endif + + if (nargin == 1 || nargin == 2) + if (! isvector (p)) + error ("polyderiv: argument must be a vector"); + endif + if (nargin == 2) + if (! isvector (a)) + error ("polyderiv: argument must be a vector"); + endif + if (nargout == 1) + ## derivative of p*a returns a single polynomial + q = polyderiv (conv (p, a)); + else + ## derivative of p/a returns numerator and denominator + d = conv (a, a); + if (numel (p) == 1) + q = -p * polyderiv (a); + elseif (numel (a) == 1) + q = a * polyderiv (p); + else + q = conv (polyderiv (p), a) - conv (p, polyderiv (a)); + q = polyreduce (q); + endif + + ## remove common factors from numerator and denominator + x = polygcd (q, d); + if (length(x) != 1) + q = deconv (q, x); + d = deconv (d, x); + endif + + ## move all the gain into the numerator + q = q/d(1); + d = d/d(1); + endif + else + lp = numel (p); + if (lp == 1) + q = 0; + return; + elseif (lp == 0) + q = []; + return; + endif + + ## Force P to be a row vector. + p = p(:).'; + + q = p(1:(lp-1)) .* [(lp-1):-1:1]; + endif + else + print_usage (); + endif + +endfunction + +%!assert(all (all (polyderiv ([1, 2, 3]) == [2, 2]))); + +%!assert(polyderiv (13) == 0); + +%!error polyderiv ([]); + +%!error polyderiv ([1, 2; 3, 4]); +
--- a/scripts/deprecated/saveimage.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/deprecated/saveimage.m Fri Aug 12 14:16:34 2011 -0400 @@ -30,8 +30,7 @@ ## Portable pixmap format. ## ## @item "ps" -## PostScript format. Note that images saved in PostScript format cannot -## be read back into Octave with loadimage. +## PostScript format. ## @end table ## ## If the fourth argument is supplied, the specified colormap will also be @@ -42,7 +41,7 @@ ## image is a gray scale image (the entries within each row of the colormap ## are equal) the gray scale ppm and PostScript image formats are used, ## otherwise the full color formats are used. -## @seealso{loadimage, save, load, colormap} +## @seealso{imread, save, load, colormap} ## @end deftypefn ## The conversion to PostScript is based on pbmtolps.c, which was
--- a/scripts/deprecated/spatan2.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spatan2 (@var{y}, @var{x}) -## This function has been deprecated. Use @code{atan2} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spatan2 (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spatan2 is obsolete and will be removed from a future version of Octave; please use atan2 instead"); - endif - - retval = atan2 (varargin{:}); - -endfunction
--- a/scripts/deprecated/spchol.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,39 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Loadable Function} {@var{r} =} spchol (@var{a}) -## @deftypefnx {Loadable Function} {[@var{r}, @var{p}] =} spchol (@var{a}) -## @deftypefnx {Loadable Function} {[@var{r}, @var{p}, @var{q}] =} spchol (@var{a}) -## This function has been deprecated. Use @code{chol} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = spchol (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spchol is obsolete and will be removed from a future version of Octave; please use chol instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = chol (varargin{:}); - -endfunction
--- a/scripts/deprecated/spchol2inv.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spchol2inv (@var{u}) -## This function has been deprecated. Use @code{chol2inv} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spchol2inv (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spchol2inv is obsolete and will be removed from a future version of Octave; please use chol2inv instead"); - endif - - retval = chol2inv (varargin{:}); - -endfunction
--- a/scripts/deprecated/spcholinv.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spcholinv (@var{u}) -## This function has been deprecated. Use @code{cholinv} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spcholinv (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spcholinv is obsolete and will be removed from a future version of Octave; please use cholinv instead"); - endif - retval = cholinv (varargin{:}); - -endfunction
--- a/scripts/deprecated/spcumprod.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spcumprod (@var{x}, @var{dim}) -## This function has been deprecated. Use @code{cumprod} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spcumprod (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spcumprod is obsolete and will be removed from a future version of Octave; please use cumprod instead"); - endif - - retval = cumprod (varargin{:}); - -endfunction
--- a/scripts/deprecated/spcumsum.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spcumsum (@var{x}, @var{dim}) -## This function has been deprecated. Use @code{cumsum} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spcumsum (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spcumsum is obsolete and will be removed from a future version of Octave; please use cumsum instead"); - endif - - retval = cumsum (varargin{:}); - -endfunction
--- a/scripts/deprecated/spdet.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Loadable Function} {[@var{d}, @var{rcond}] =} spdet (@var{a}) -## This function has been deprecated. Use @code{det} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = spdet (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spdet is obsolete and will be removed from a future version of Octave; please use det instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = det (varargin{:}); - -endfunction
--- a/scripts/deprecated/spdiag.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spdiag (@var{v}, @var{k}) -## This function has been deprecated. Use @code{sparse (diag (@dots{}))} -## instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spdiag (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spdiag is obsolete and will be removed from a future version of Octave; please use sparse (diag (...)) instead"); - endif - - retval = sparse (diag (varargin{:})); - -endfunction
--- a/scripts/deprecated/spfind.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Loadable Function} {} spfind (@var{x}) -## @deftypefnx {Loadable Function} {} spfind (@var{x}, @var{n}) -## @deftypefnx {Loadable Function} {} spfind (@var{x}, @var{n}, @var{direction}) -## @deftypefnx {Loadable Function} {[@var{i}, @var{j}, @var{v}} spfind (@dots{}) -## This function has been deprecated. Use @code{find} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = spfind (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spfind is obsolete and will be removed from a future version of Octave; please use find instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = find (varargin{:}); - -endfunction
--- a/scripts/deprecated/spinv.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{x}, @var{rcond}] =} spinv (@var{a}) -## This function has been deprecated. Use @code{inv} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = spinv (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spinv is obsolete and will be removed from a future version of Octave; please use inv instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = inv (varargin{:}); - -endfunction
--- a/scripts/deprecated/spkron.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -## Copyright (C) 2008-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spkron (@var{a}, @var{b}) -## This function has been deprecated. Use @code{kron} instead. -## @end deftypefn - -## Author: jwe - -## Deprecated in version 3.2 - -function retval = spkron (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spkron is obsolete and will be removed from a future version of Octave; please use kron instead"); - endif - - retval = kron (varargin{:}); - -endfunction
--- a/scripts/deprecated/splchol.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Loadable Function} {@var{l} =} splchol (@var{a}) -## @deftypefnx {Loadable Function} {[@var{l}, @var{p}] =} splchol (@var{a}) -## @deftypefnx {Loadable Function} {[@var{l}, @var{p}, @var{q}] =} splchol (@var{a}) -## This function has been deprecated. Use @code{chol (@dots{},'lower')} -## instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = splchol (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "splchol is obsolete and will be removed from a future version of Octave; please use chol instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = chol (varargin{:}, "lower"); - -endfunction
--- a/scripts/deprecated/split.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,130 +0,0 @@ -## Copyright (C) 1996-2011 Kurt Hornik -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} split (@var{s}, @var{t}, @var{n}) -## This function has been deprecated. Use @code{char (strsplit (s, t))} -## instead. -## @end deftypefn - -## Divides the string @var{s} into pieces separated by @var{t}, returning -## the result in a string array (padded with blanks to form a valid -## matrix). If the optional input @var{n} is supplied, split @var{s} -## into at most @var{n} different pieces. -## -## For example, -## -## @example -## split ("Test string", "t") -## @result{} -## "Tes " -## " s " -## "ring" -## @end example -## -## @example -## split ("Test string", "t s", 2) -## @result{} -## "Tes " -## "tring" -## @end example -## @seealso{strtok, index} -## @end deftypefn - -## Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> -## Adapted-By: jwe - -## Deprecated in version 3.2 - -function m = split (s, t, n) - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "split is obsolete and will be removed from a future version of Octave; please use strsplit instead"); - endif - - if (nargin == 2 || nargin == 3) - if (nargin == 2) - n = length (s); - endif - - if (ischar (s) && ischar (t)) - - l_s = length (s); - l_t = length (t); - - if (l_s == 0) - m = ""; - return; - elseif (l_t == 0) - m = s'; - return; - elseif (l_s < l_t) - error ("split: S must not be shorter than T"); - endif - - if (min (size (s)) != 1 || min (size (t)) != 1) - error("split: multi-line strings are not supported"); - endif - - ind = findstr (s, t, 0); - if (length (ind) == 0) - m = s; - return; - elseif (n - 1 < length(ind)) - ind = ind(1:n-1); - endif - ind2 = [1, ind+l_t]; - ind = [ind, l_s+1]; - - ind_diff = ind-ind2; - - ## Create a matrix of the correct size that's filled with spaces. - m_rows = length (ind); - m_cols = max (ind_diff); - m = repmat (" ", m_rows, m_cols); - - ## Copy the strings to the matrix. - for i = 1:length (ind) - tmp = ind2(i):(ind(i)-1); - m(i,1:length(tmp)) = s(tmp); - endfor - else - error ("split: both S and T must be strings"); - endif - else - print_usage (); - endif - -endfunction - -%!assert(all (all (split ("Test string", "t") == ["Tes "; " s "; "ring"]))); - -%!error split (); - -%!assert(all (strcmp (split ("foo bar baz", " ", 2), ["foo"; "bar baz"]))); - -%!error split ("foo", "bar", 3, 4); - -%!assert (all (strcmp (split("road//to/hell","/"), ["road"; " "; "to "; "hell"]))) - -%!assert (all (strcmp (split("/road/to/hell/","/"), [" "; "road"; "to "; "hell"; " "]))) - -
--- a/scripts/deprecated/splu.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,48 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Loadable Function} {[@var{l}, @var{u}] =} splu (@var{a}) -## @deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}] =} splu (@var{a}) -## @deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}, @var{Q}] =} splu (@var{a}) -## @deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}, @var{Q}] =} splu (@dots{}, @var{thres}) -## @deftypefnx {Loadable Function} {[@var{l}, @var{u}, @var{P}] =} splu (@dots{}, @var{Q}) -## This function has been deprecated. Use @code{lu} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = splu (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "splu is obsolete and will be removed from a future version of Octave; please use lu instead"); - endif - - for i = 2 : nargin - arg = varargin {i}; - if (! isscalar (arg)) - error ("splu: Can no longer treat input column permutations"); - endif - endfor - - varargout = cell (nargout, 1); - [ varargout{:} ] = lu (varargin{:}); - -endfunction
--- a/scripts/deprecated/spmax.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Mapping Function} {} spmax (@var{x}, @var{y}, @var{dim}) -## @deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} spmax (@var{x}) -## This function has been deprecated. Use @code{max} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = spmax (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spmax is obsolete and will be removed from a future version of Octave; please use max instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = max (varargin{:}); - -endfunction
--- a/scripts/deprecated/spmin.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Mapping Function} {} spmin (@var{x}, @var{y}, @var{dim}) -## @deftypefnx {Mapping Function} {[@var{w}, @var{iw}] =} spmin (@var{x}) -## This function has been deprecated. Use @code{min} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = spmin (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spmin is obsolete and will be removed from a future version of Octave; please use min instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = min (varargin{:}); - -endfunction
--- a/scripts/deprecated/spprod.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spprod (@var{x}, @var{dim}) -## This function has been deprecated. Use @code{prod} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spprod (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spprod is obsolete and will be removed from a future version of Octave; please use prod instead"); - endif - - retval = prod (varargin{:}); - -endfunction
--- a/scripts/deprecated/spqr.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Loadable Function} {@var{r} =} spqr (@var{a}) -## @deftypefnx {Loadable Function} {@var{r} =} spqr (@var{a}, 0) -## @deftypefnx {Loadable Function} {[@var{c}, @var{r}] =} spqr (@var{a}, @var{b}) -## @deftypefnx {Loadable Function} {[@var{c}, @var{r}] =} spqr (@var{a}, @var{b}, 0) -## This function has been deprecated. Use @code{qr} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function varargout = spqr (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spqr is obsolete and will be removed from a future version of Octave; please use qr instead"); - endif - - varargout = cell (nargout, 1); - [ varargout{:} ] = qr (varargin{:}); - -endfunction
--- a/scripts/deprecated/spsum.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,36 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spsum (@var{x}, @var{dim}) -## This function has been deprecated. Use @code{sum} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spsum (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spsum is obsolete and will be removed from a future version of Octave; please use sum instead"); - endif - - retval = sum (varargin{:}); - -endfunction
--- a/scripts/deprecated/spsumsq.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} spsumsq (@var{x}, @var{dim}) -## This function has been deprecated. Use @code{sumsq} instead. -## @end deftypefn - -## Deprecated in version 3.2 - -function retval = spsumsq (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "spsumsq is obsolete and will be removed from a future version of Octave; please use sumsq instead"); - endif - retval = sumsq (varargin{:}); - -endfunction
--- a/scripts/deprecated/str2mat.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -## Copyright (C) 1996-2011 Kurt Hornik -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} str2mat (@var{s_1}, @dots{}, @var{s_n}) -## Return a matrix containing the strings @var{s_1}, @dots{}, @var{s_n} as -## its rows. Each string is padded with blanks in order to form a valid -## matrix. -## -## This function is modelled after @sc{matlab}. In Octave, you can create -## a matrix of strings by @code{[@var{s_1}; @dots{}; @var{s_n}]} even if -## the strings are not all the same length. -## @end deftypefn - -## Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> -## Adapted-By: jwe - -## Deprecated in version 3.2 - -function retval = str2mat (varargin) - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "str2mat is obsolete and will be removed from a future version of Octave; please use char instead"); - endif - - retval = char (varargin{:}); - -endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/studentize.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,94 @@ +## Copyright (C) 1995-2011 Kurt Hornik +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} studentize (@var{x}) +## @deftypefnx {Function File} {} studentize (@var{x}, @var{dim}) +## If @var{x} is a vector, subtract its mean and divide by its standard +## deviation. +## +## If @var{x} is a matrix, do the above along the first non-singleton +## dimension. +## If the optional argument @var{dim} is given, operate along this dimension. +## @seealso{center} +## @end deftypefn + +## Author: KH <Kurt.Hornik@wu-wien.ac.at> +## Description: Subtract mean and divide by standard deviation + +function t = studentize (x, dim) + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "studentize is obsolete and will be removed from a future version of Octave; please use zscore instead"); + endif + + if (nargin != 1 && nargin != 2) + print_usage (); + endif + + if (! isnumeric(x)) + error ("studentize: X must be a numeric vector or matrix"); + endif + + if (isinteger (x)) + x = double (x); + endif + + nd = ndims (x); + sz = size (x); + if (nargin != 2) + ## Find the first non-singleton dimension. + dim = find (sz > 1, 1); + if (isempty (dim)) + dim = 1; + endif + else + if (!(isscalar (dim) && dim == fix (dim)) + || !(1 <= dim && dim <= nd)) + error ("studentize: DIM must be an integer and a valid dimension"); + endif + endif + + c = sz(dim); + if (c == 0) + t = x; + else + idx = ones (1, nd); + idx(dim) = c; + t = x - repmat (mean (x, dim), idx); + t = t ./ repmat (max (cat (dim, std(t, [], dim), ! any (t, dim)), [], dim), idx); + endif + +endfunction + +%!assert(studentize ([1,2,3]), [-1,0,1]) +%!assert(studentize (int8 ([1,2,3])), [-1,0,1]) +#%!assert(studentize (ones (3,2,0,2)), zeros (3,2,0,2)) +%!assert(studentize ([2,0,-2;0,2,0;-2,-2,2]), [1,0,-1;0,1,0;-1,-1,1]) + +%% Test input validation +%!error studentize () +%!error studentize (1, 2, 3) +%!error studentize ([true true]) +%!error studentize (1, ones(2,2)) +%!error studentize (1, 1.5) +%!error studentize (1, 0) +%!error studentize (1, 3) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/deprecated/sylvester_matrix.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,69 @@ +## Copyright (C) 1996-2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} sylvester_matrix (@var{k}) +## Return the Sylvester matrix of order +## @tex +## $n = 2^k$. +## @end tex +## @ifnottex +## n = 2^@var{k}. +## @end ifnottex +## +## @seealso{toeplitz, hankel} +## @end deftypefn + +## Author: jwe + +function retval = sylvester_matrix (k) + + persistent warned = false; + if (! warned) + warned = true; + warning ("Octave:deprecated-function", + "sylvester_matrix is obsolete and will be removed from a future version of Octave; please use hadamard(2^k) instead"); + endif + + if (nargin != 1) + print_usage (); + endif + + if (isscalar (k)) + if (k < 1) + retval = 1; + else + tmp = sylvester_matrix (k-1); + retval = [tmp, tmp; tmp, -tmp]; + endif + else + error ("sylvester_matrix: expecting scalar argument"); + endif + +endfunction + +%!assert((sylvester_matrix (1) == [1, 1; 1, -1] +%! && (sylvester_matrix (2) +%! == [1, 1, 1, 1; 1, -1, 1, -1; 1, 1, -1, -1; 1, -1, -1, 1]))); + +%!error sylvester_matrix ([1, 2; 3, 4]); + +%!error sylvester_matrix (); + +%!error sylvester_matrix (1, 2); +
--- a/scripts/deprecated/unmark_command.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -## Copyright (C) 2009-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Built-in Function} {} unmark_command (@var{name}) -## This function is obsolete and will be removed from a future -## version of Octave. -## @end deftypefn - -## Author: jwe - -## Deprecated in version 3.2 - -function unmark_command () - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "unmark_command is obsolete and will be removed from a future version of Octave"); - endif - -endfunction
--- a/scripts/deprecated/unmark_rawcommand.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -## Copyright (C) 2009-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Built-in Function} {} unmark_rawcommand (@var{name}) -## This function is obsolete and will be removed from a future -## version of Octave. -## @end deftypefn - -## Author: jwe - -## Deprecated in version 3.2 - -function unmark_rawcommand () - - persistent warned = false; - if (! warned) - warned = true; - warning ("Octave:deprecated-function", - "unmark_rawcommand is obsolete and will be removed from a future version of Octave"); - endif - -endfunction
--- a/scripts/elfun/lcm.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -## Copyright (C) 1994-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Mapping Function} {} lcm (@var{x}, @var{y}) -## @deftypefnx {Mapping Function} {} lcm (@var{x}, @var{y}, @dots{}) -## Compute the least common multiple of @var{x} and @var{y}, -## or of the list of all arguments. All elements must be the same size or -## scalar. -## @seealso{factor, gcd} -## @end deftypefn - -## Author: KH <Kurt.Hornik@wu-wien.ac.at> -## Created: 16 September 1994 -## Adapted-By: jwe - -function l = lcm (varargin) - - if (nargin > 1) - if (common_size (varargin{:}) != 0) - error ("lcm: all args must be of the same size or scalar"); - elseif (! all (cellfun (@isnumeric, varargin))) - error ("lcm: all arguments must be numeric"); - endif - - l = varargin{1}; - for i = 2:nargin - x = varargin{i}; - msk = l == 0 & x == 0; - l .*= x ./ gcd (l, x); - l(msk) = 0; - endfor - else - print_usage (); - endif - -endfunction - -%!assert(lcm (3, 5, 7, 15) == 105); - -%!error lcm (); - -%!test -%! s.a = 1; -%! fail("lcm (s)"); -
--- a/scripts/elfun/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/elfun/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -20,7 +20,6 @@ elfun/csc.m \ elfun/cscd.m \ elfun/csch.m \ - elfun/lcm.m \ elfun/sec.m \ elfun/secd.m \ elfun/sech.m \
--- a/scripts/general/accumarray.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/accumarray.m Fri Aug 12 14:16:34 2011 -0400 @@ -72,7 +72,7 @@ endif if (iscell (subs)) - subs = cellfun (@vec, subs, "uniformoutput", false); + subs = cellfun ("vec", subs, "uniformoutput", false); ndims = numel (subs); if (ndims == 1) subs = subs{1}; @@ -149,7 +149,7 @@ if (ndims > 1) if (isempty (sz)) if (iscell (subs)) - sz = cellfun (@max, subs); + sz = cellfun ("max", subs); else sz = max (subs, [], 1); endif
--- a/scripts/general/arrayfun.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/arrayfun.m Fri Aug 12 14:16:34 2011 -0400 @@ -154,7 +154,7 @@ args = varargin(1:nargs); opts = varargin(nargs+1:end); - args = cellfun (@num2cell, args, "UniformOutput", false, + args = cellfun ("num2cell", args, "UniformOutput", false, "ErrorHandler", @arg_class_error); [varargout{1:max(1, nargout)}] = cellfun (func, args{:}, opts{:});
--- a/scripts/general/bitget.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/bitget.m Fri Aug 12 14:16:34 2011 -0400 @@ -79,3 +79,31 @@ C = bitand (A, bitshift (_conv (1), uint8 (n) - uint8 (1))) != _conv (0); endfunction + +%!error bitget (1); +%!error bitget (1, 2, 3); + +%!test +%! assert (bitget ([4, 14], [3, 3]), logical ([1, 1])); +%! pfx = {"", "u"}; +%! for i = 1:2 +%! for prec = [8, 16, 32, 64] +%! fcn = str2func (sprintf ("%sint%d", pfx{i}, prec)); +%! assert (bitget (fcn ([4, 14]), [3, 3]), logical ([1, 1])); +%! endfor +%! endfor + +%!error bitget (0, 0); +%!error bitget (0, 55); + +%!error bitget (int8 (0), 9); +%!error bitget (uint8 (0), 9); + +%!error bitget (int16 (0), 17); +%!error bitget (uint16 (0), 17); + +%!error bitget (int32 (0), 33); +%!error bitget (uint32 (0), 33); + +%!error bitget (int64 (0), 65); +%!error bitget (uint64 (0), 65);
--- a/scripts/general/bitset.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/bitset.m Fri Aug 12 14:16:34 2011 -0400 @@ -92,3 +92,31 @@ endif endfunction + +%!error bitset (1); +%!error bitset (1, 2, 3, 4); + +%!test +%! assert (bitset ([0, 10], [3, 3]), [4, 14]); +%! pfx = {"", "u"}; +%! for i = 1:2 +%! for prec = [8, 16, 32, 64] +%! fcn = str2func (sprintf ("%sint%d", pfx{i}, prec)); +%! assert (bitset (fcn ([0, 10]), [3, 3]), fcn ([4, 14])); +%! endfor +%! endfor + +%!error bitset (0, 0); +%!error bitset (0, 55); + +%!error bitset (int8 (0), 9); +%!error bitset (uint8 (0), 9); + +%!error bitset (int16 (0), 17); +%!error bitset (uint16 (0), 17); + +%!error bitset (int32 (0), 33); +%!error bitset (uint32 (0), 33); + +%!error bitset (int64 (0), 65); +%!error bitset (uint64 (0), 65);
--- a/scripts/general/blkdiag.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/blkdiag.m Fri Aug 12 14:16:34 2011 -0400 @@ -33,7 +33,7 @@ print_usage (); endif - if (! all (cellfun (@isnumeric, varargin))) + if (! all (cellfun ("isnumeric", varargin))) error ("blkdiag: all arguments must be numeric"); endif
--- a/scripts/general/cell2mat.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/cell2mat.m Fri Aug 12 14:16:34 2011 -0400 @@ -43,11 +43,11 @@ else ## We only want numeric, logical, and char matrices. - valid = cellfun (@isnumeric, c); - valid |= cellfun (@islogical, c); - valid |= cellfun (@ischar, c); - validc = cellfun (@iscell, c); - valids = cellfun (@isstruct, c); + valid = cellfun ("isnumeric", c); + valid |= cellfun ("islogical", c); + valid |= cellfun ("isclass", c, "char"); + validc = cellfun ("isclass", c, "cell"); + valids = cellfun ("isclass", c, "struct"); if (! all (valid(:)) && ! all (validc(:)) && ! all (valids(:))) error ("cell2mat: wrong type elements or mixed cells, structs and matrices"); @@ -71,7 +71,7 @@ endif xdim = [1:idim-1, idim+1:nd]; cc = num2cell (c, xdim); - c = cellfun (@cat, {idim}, cc{:}, "uniformoutput", false); + c = cellfun ("cat", {idim}, cc{:}, "uniformoutput", false); endfor m = c{1}; endif
--- a/scripts/general/colon.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/colon.m Fri Aug 12 14:16:34 2011 -0400 @@ -38,3 +38,7 @@ error ("colon: not defined for class \"%s\"", class(varargin{1})); endif endfunction + +%!error colon (1) + +## FIXME -- what does colon () mean since it doesn't set a return value?
--- a/scripts/general/common_size.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/common_size.m Fri Aug 12 14:16:34 2011 -0400 @@ -52,7 +52,7 @@ endif ## Find scalar args. - nscal = cellfun (@numel, varargin) != 1; + nscal = cellfun ("numel", varargin) != 1; i = find (nscal, 1); @@ -60,7 +60,7 @@ errorcode = 0; varargout = varargin; else - match = cellfun (@size_equal, varargin, varargin(i)); + match = cellfun ("size_equal", varargin, varargin(i)); if (any (nscal &! match)) errorcode = 1; varargout = varargin; @@ -78,3 +78,13 @@ endif endif endfunction + +%!error common_size (); + +%!test +%! m = [1,2;3,4]; +%! [err, a, b, c] = common_size (m, 3, 5); +%! assert (err, 0); +%! assert (a, m); +%! assert (b, [3,3;3,3]); +%! assert (c, [5,5;5,5]);
--- a/scripts/general/dblquad.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/dblquad.m Fri Aug 12 14:16:34 2011 -0400 @@ -37,22 +37,23 @@ ## ## The optional argument @var{quadf} specifies which underlying integrator ## function to use. Any choice but @code{quad} is available and the default -## is @code{quadgk}. +## is @code{quadcc}. ## ## Additional arguments, are passed directly to @var{f}. To use the default -## value for @var{tol} or @var{quadf} one may pass an empty matrix ([]). +## value for @var{tol} or @var{quadf} one may pass ':' or an empty matrix ([]). ## @seealso{triplequad, quad, quadv, quadl, quadgk, quadcc, trapz} ## @end deftypefn -function q = dblquad(f, xa, xb, ya, yb, tol, quadf, varargin) +function q = dblquad (f, xa, xb, ya, yb, tol = 1e-6, quadf = @quadcc, varargin) + if (nargin < 5) print_usage (); endif - if (nargin < 6 || isempty (tol)) + if (isempty (tol)) tol = 1e-6; endif - if (nargin < 7 || isempty (quadf)) - quadf = @quadgk; + if (isempty (quadf)) + quadf = @quadcc; endif inner = @__dblquad_inner__; @@ -72,10 +73,10 @@ endfor endfunction -%% Nasty integrand to show quadgk off +%% Nasty integrand to show quadcc off %!assert (dblquad (@(x,y) 1 ./ (x+y), 0, 1, 0, 1), 2*log(2), 1e-6) -%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, [], @quadgk), pi * erf(1).^2, 1e-6) -%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, [], @quadl), pi * erf(1).^2, 1e-6) -%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, [], @quadv), pi * erf(1).^2, 1e-6) +%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, 1e-6, @quadgk), pi * erf(1).^2, 1e-6) +%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, 1e-6, @quadl), pi * erf(1).^2, 1e-6) +%!assert (dblquad (@(x,y) exp(-x.^2 - y.^2) , -1, 1, -1, 1, 1e-6, @quadv), pi * erf(1).^2, 1e-6)
--- a/scripts/general/flipdim.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/flipdim.m Fri Aug 12 14:16:34 2011 -0400 @@ -43,9 +43,10 @@ endif nd = ndims (x); + sz = size (x); if (nargin == 1) ## Find the first non-singleton dimension. - [~, dim] = min (size (x) != 1); + (dim = find (sz > 1, 1)) || (dim = 1); elseif (! (isscalar (dim) && isindex (dim))) error ("flipdim: DIM must be a positive integer"); endif @@ -55,3 +56,12 @@ y = x(idx{:}); endfunction + +%!error flipdim (); +%!error flipdim (1, 2, 3); + +%!assert (flipdim ([1,2;3,4]), flipdim ([1,2 ; 3,4], 1)); +%!assert (flipdim ([1,2;3,4], 2), [2,1;4,3]); +%!assert (flipdim ([1,2;3,4], 3), [1,2;3,4]); + +## FIXME -- we need tests for multidimensional arrays.
--- a/scripts/general/int2str.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/int2str.m Fri Aug 12 14:16:34 2011 -0400 @@ -49,31 +49,33 @@ function retval = int2str (n) - if (nargin == 1) - n = round (real(n)); - sz = size(n); - nd = ndims (n); - nc = columns (n); - if (nc > 1) - idx = cell (); - for i = 1:nd - idx{i} = 1:sz(i); - endfor - idx(2) = 1; - ifmt = get_fmt (n(idx{:}), 0); - idx(2) = 2:sz(2); - rfmt = get_fmt (n(idx{:}), 2); - fmt = cstrcat (ifmt, repmat (rfmt, 1, nc-1), "\n"); - else - fmt = cstrcat (get_fmt (n, 0), "\n"); - endif - tmp = sprintf (fmt, permute (n, [2, 1, 3 : nd])); - tmp(end) = ""; - retval = char (strsplit (tmp, "\n")); - else + if (nargin != 1) print_usage (); endif + if (isempty (n)) + retval = ''; + return; + endif + + n = round (real(n)); + sz = size(n); + nd = ndims (n); + nc = columns (n); + if (nc > 1) + idx = repmat ({':'}, nd, 1); + idx(2) = 1; + ifmt = get_fmt (n(idx{:}), 0); + idx(2) = 2:sz(2); + rfmt = get_fmt (n(idx{:}), 2); + fmt = cstrcat (ifmt, repmat (rfmt, 1, nc-1), "\n"); + else + fmt = cstrcat (get_fmt (n, 0), "\n"); + endif + tmp = sprintf (fmt, permute (n, [2, 1, 3 : nd])); + tmp(end) = ""; + retval = char (strsplit (tmp, "\n")); + endfunction function fmt = get_fmt (x, sep) @@ -112,8 +114,10 @@ endfunction -%!assert(strcmp (int2str (-123), "-123") && strcmp (int2str (1.2), "1")); +%!assert (strcmp (int2str (-123), "-123") && strcmp (int2str (1.2), "1")); %!assert (all (int2str ([1, 2, 3; 4, 5, 6]) == ["1 2 3";"4 5 6"])); +%!assert (int2str([]), ""); + %!error int2str (); %!error int2str (1, 2);
--- a/scripts/general/interp1.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/interp1.m Fri Aug 12 14:16:34 2011 -0400 @@ -43,7 +43,7 @@ ## Piecewise cubic Hermite interpolating polynomial ## ## @item 'cubic' -## Cubic interpolation from four nearest neighbors +## Cubic interpolation (same as @code{pchip}) ## ## @item 'spline' ## Cubic spline interpolation---smooth first and second derivatives @@ -112,7 +112,7 @@ method = "linear"; extrap = NA; xi = []; - pp = false; + ispp = false; firstnumeric = true; if (nargin > 2) @@ -123,7 +123,7 @@ if (strcmp ("extrap", arg)) extrap = "extrap"; elseif (strcmp ("pp", arg)) - pp = true; + ispp = true; else method = arg; endif @@ -138,7 +138,7 @@ endfor endif - if (isempty (xi) && firstnumeric && ! pp) + if (isempty (xi) && firstnumeric && ! ispp) xi = y; y = x; x = 1:numel(y); @@ -150,9 +150,8 @@ szx = size (xi); if (isvector (y)) y = y(:); - elseif (isvector (xi)) - szx = length (xi); endif + szy = size (y); y = y(:,:); [ny, nc] = size (y); @@ -191,147 +190,85 @@ switch (method) case "nearest" - if (pp) - yi = mkpp ([x(1); (x(1:nx-1)+x(2:nx))/2; x(nx)], y, szy(2:end)); + pp = mkpp ([x(1); (x(1:nx-1)+x(2:nx))/2; x(nx)], shiftdim (y, 1), szy(2:end)); + pp.orient = "first"; + + if (ispp) + yi = pp; else - idx = lookup (0.5*(x(1:nx-1)+x(2:nx)), xi) + 1; - yi = y(idx,:); + yi = ppval (pp, reshape (xi, szx)); endif case "*nearest" - if (pp) - yi = mkpp ([x(1); x(1)+[0.5:(nx-1)]'*dx; x(nx)], y, szy(2:end)); + pp = mkpp ([x(1), x(1)+[0.5:(nx-1)]*dx, x(nx)], shiftdim (y, 1), szy(2:end)); + pp.orient = "first"; + if (ispp) + yi = pp; else - idx = max (1, min (ny, floor((xi-x(1))/dx+1.5))); - yi = y(idx,:); + yi = ppval(pp, reshape (xi, szx)); endif case "linear" dy = diff (y); - dx = diff (x); - if (pp) - coefs = [dy./dx, y(1:nx-1)]; - xx = x; - if (have_jumps) - ## Omit zero-size intervals. - coefs(jumps) = []; - xx(jumps) = []; - endif - yi = mkpp (xx, coefs, szy(2:end)); + dx = diff (x); + dx = repmat (dx, [1 size(dy)(2:end)]); + coefs = [(dy./dx).'(:), y(1:nx-1, :).'(:)]; + xx = x; + + if (have_jumps) + ## Omit zero-size intervals. + coefs(jumps, :) = []; + xx(jumps) = []; + endif + + pp = mkpp (xx, coefs, szy(2:end)); + pp.orient = "first"; + + if (ispp) + yi = pp; else - ## find the interval containing the test point - idx = lookup (x, xi, "lr"); - ## use the endpoints of the interval to define a line - s = (xi - x(idx))./dx(idx); - yi = bsxfun (@times, s, dy(idx,:)) + y(idx,:); - if (have_jumps) - ## Fix the corner cases of discontinuities at boundaries. - ## Internal discontinuities already handled correctly. - if (jumps (1)) - mask = xi < x(1); - yi(mask,:) = y(1*ones (1, sum (mask)),:); - endif - if (jumps(nx-1)) - mask = xi >= x(nx); - yi(mask,:) = y(nx*ones (1, sum (mask)),:); - endif - endif + yi = ppval(pp, reshape (xi, szx)); endif + case "*linear" dy = diff (y); - if (pp) - yi = mkpp (x(1) + [0:ny-1]*dx, [dy./dx, y(1:end-1)], szy(2:end)); + coefs = [(dy/dx).'(:), y(1:nx-1, :).'(:)]; + pp = mkpp (x, coefs, szy(2:end)); + pp.orient = "first"; + + if (ispp) + yi = pp; else - ## find the interval containing the test point - t = (xi - x(1))/dx + 1; - idx = max (1, min (ny - 1, floor (t))); + yi = ppval(pp, reshape (xi, szx)); + endif - ## use the endpoints of the interval to define a line - s = t - idx; - yi = bsxfun (@times, s, dy(idx,:)) + y(idx,:); - endif - case {"pchip", "*pchip"} + case {"pchip", "*pchip", "cubic", "*cubic"} if (nx == 2 || starmethod) x = linspace (x(1), x(nx), ny); endif - ## Note that pchip's arguments are transposed relative to interp1 - if (pp) - yi = pchip (x.', y.'); - yi.d = szy(2:end); - else - yi = pchip (x.', y.', xi.').'; - endif - - case {"cubic", "*cubic"} - if (nx < 4 || ny < 4) - error ("interp1: table too short"); - endif - - ## FIXME Is there a better way to treat pp return and *cubic - if (starmethod && ! pp) - ## From: Miloje Makivic - ## http://www.npac.syr.edu/projects/nasa/MILOJE/final/node36.html - t = (xi - x(1))/dx + 1; - idx = max (min (floor (t), ny-2), 2); - t = t - idx; - t2 = t.*t; - tp = 1 - 0.5*t; - a = (1 - t2).*tp; - b = (t2 + t).*tp; - c = (t2 - t).*tp/3; - d = (t2 - 1).*t/6; - J = ones (1, nc); - - yi = a(:,J) .* y(idx,:) + b(:,J) .* y(idx+1,:) ... - + c(:,J) .* y(idx-1,:) + d(:,J) .* y(idx+2,:); + + if (ispp) + y = shiftdim (reshape (y, szy), 1); + yi = pchip (x, y); else - if (starmethod) - x = linspace (x(1), x(nx), ny).'; - nx = ny; - endif - - idx = lookup (x(2:nx-1), xi, "lr"); - - ## Construct cubic equations for each interval using divided - ## differences (computation of c and d don't use divided differences - ## but instead solve 2 equations for 2 unknowns). Perhaps - ## reformulating this as a lagrange polynomial would be more efficient. - i = 1:nx-3; - J = ones (1, nc); - dx = diff (x); - dx2 = x(i+1).^2 - x(i).^2; - dx3 = x(i+1).^3 - x(i).^3; - a = diff (y, 3)./dx(i,J).^3/6; - b = (diff (y(1:nx-1,:), 2)./dx(i,J).^2 - 6*a.*x(i+1,J))/2; - c = (diff (y(1:nx-2,:), 1) - a.*dx3(:,J) - b.*dx2(:,J))./dx(i,J); - d = y(i,:) - ((a.*x(i,J) + b).*x(i,J) + c).*x(i,J); - - if (pp) - xs = [x(1);x(3:nx-2)]; - yi = mkpp ([x(1);x(3:nx-2);x(nx)], - [a(:), (b(:) + 3.*xs(:,J).*a(:)), ... - (c(:) + 2.*xs(:,J).*b(:) + 3.*xs(:,J)(:).^2.*a(:)), ... - (d(:) + xs(:,J).*c(:) + xs(:,J).^2.*b(:) + ... - xs(:,J).^3.*a(:))], szy(2:end)); - else - yi = ((a(idx,:).*xi(:,J) + b(idx,:)).*xi(:,J) ... - + c(idx,:)).*xi(:,J) + d(idx,:); - endif + y = shiftdim (y, 1); + yi = pchip (x, y, reshape (xi, szx)); endif case {"spline", "*spline"} if (nx == 2 || starmethod) x = linspace(x(1), x(nx), ny); endif - ## Note that spline's arguments are transposed relative to interp1 - if (pp) - yi = spline (x.', y.'); - yi.d = szy(2:end); + + if (ispp) + y = shiftdim (reshape (y, szy), 1); + yi = spline (x, y); else - yi = spline (x.', y.', xi.').'; + y = shiftdim (y, 1); + yi = spline (x, y, reshape (xi, szx)); endif otherwise error ("interp1: invalid method '%s'", method); endswitch - if (! pp) + if (! ispp) if (! ischar (extrap)) ## determine which values are out of range and set them to extrap, ## unless extrap == "extrap". @@ -339,10 +276,24 @@ maxx = max (x(1), x(nx)); outliers = xi < minx | ! (xi <= maxx); # this catches even NaNs - yi(outliers, :) = extrap; + if (size_equal (outliers, yi)) + yi(outliers) = extrap; + yi = reshape (yi, szx); + elseif (!isvector (yi)) + if (strcmp (method, "pchip") || strcmp (method, "*pchip") + ||strcmp (method, "cubic") || strcmp (method, "*cubic") + ||strcmp (method, "spline") || strcmp (method, "*spline")) + yi(:, outliers) = extrap; + yi = shiftdim(yi, 1); + else + yi(outliers, :) = extrap; + endif + else + yi(outliers.') = extrap; + endif endif - - yi = reshape (yi, [szx, szy(2:end)]); + else + yi.orient = "first"; endif endfunction @@ -394,6 +345,7 @@ %! %-------------------------------------------------------- %! % confirm that interpolated function matches the original +##FIXME: add test for n-d arguments here ## For each type of interpolated test, confirm that the interpolated ## value at the knots match the values at the knots. Points away @@ -595,7 +547,6 @@ %!assert (interp1(1:2,1:2,1.4,"nearest"),1); %!error interp1(1,1,1, "linear"); %!assert (interp1(1:2,1:2,1.4,"linear"),1.4); -%!error interp1(1:3,1:3,1, "cubic"); %!assert (interp1(1:4,1:4,1.4,"cubic"),1.4); %!assert (interp1(1:2,1:2,1.1, "spline"), 1.1); %!assert (interp1(1:3,1:3,1.4,"spline"),1.4); @@ -604,7 +555,6 @@ %!assert (interp1(1:2:4,1:2:4,1.4,"*nearest"),1); %!error interp1(1,1,1, "*linear"); %!assert (interp1(1:2:4,1:2:4,[0,1,1.4,3,4],"*linear"),[NA,1,1.4,3,NA]); -%!error interp1(1:3,1:3,1, "*cubic"); %!assert (interp1(1:2:8,1:2:8,1.4,"*cubic"),1.4); %!assert (interp1(1:2,1:2,1.3, "*spline"), 1.3); %!assert (interp1(1:2:6,1:2:6,1.4,"*spline"),1.4); @@ -612,5 +562,5 @@ %!assert (interp1([3,2,1],[3,2,2],2.5),2.5) %!assert (interp1 ([1,2,2,3,4],[0,1,4,2,1],[-1,1.5,2,2.5,3.5], "linear", "extrap"), [-2,0.5,4,3,1.5]) -%!assert (interp1 ([4,4,3,2,0],[0,1,4,2,1],[1.5,4,4.5], "linear"), [0,1,NA]) +%!assert (interp1 ([4,4,3,2,0],[0,1,4,2,1],[1.5,4,4.5], "linear"), [1.75,1,NA]) %!assert (interp1 (0:4, 2.5), 1.5)
--- a/scripts/general/interp3.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/interp3.m Fri Aug 12 14:16:34 2011 -0400 @@ -92,7 +92,7 @@ error ("interp3: expect 3-dimensional array of values"); endif x = varargin (2:4); - if (any (! cellfun (@isvector, x))) + if (any (! cellfun ("isvector", x))) for i = 2 : 3 if (! size_equal (x{1}, x{i})) error ("interp3: dimensional mismatch"); @@ -109,7 +109,7 @@ error ("interp3: expect 3-dimensional array of values"); endif x = varargin (1:3); - if (any (! cellfun (@isvector, x))) + if (any (! cellfun ("isvector", x))) for i = 2 : 3 if (! size_equal (x{1}, x{i}) || ! size_equal (x{i}, v)) error ("interp3: dimensional mismatch"); @@ -119,7 +119,7 @@ x{1} = permute (x{1}, [2, 1, 3]); endif y = varargin (5:7); - if (any (! cellfun (@isvector, y))) + if (any (! cellfun ("isvector", y))) for i = 2 : 3 if (! size_equal (y{1}, y{i})) error ("interp3: dimensional mismatch");
--- a/scripts/general/interpft.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/interpft.m Fri Aug 12 14:16:34 2011 -0400 @@ -76,10 +76,8 @@ k = floor (m / 2); sz = size (x); sz(1) = n * inc - m; - idx = cell (nd, 1); - for i = 2:nd - idx{i} = 1:sz(i); - endfor + + idx = repmat ({':'}, nd, 1); idx{1} = 1:k; z = cat (1, y(idx{:}), zeros (sz)); idx{1} = k+1:m;
--- a/scripts/general/interpn.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/interpn.m Fri Aug 12 14:16:34 2011 -0400 @@ -124,7 +124,7 @@ error ("interpn: wrong number or incorrectly formatted input arguments"); endif - if (any (! cellfun (@isvector, x))) + if (any (! cellfun ("isvector", x))) for i = 2 : nd if (! size_equal (x{1}, x{i}) || ! size_equal (x{i}, v)) error ("interpn: dimensional mismatch"); @@ -140,8 +140,8 @@ method = tolower (method); - all_vectors = all (cellfun (@isvector, y)); - different_lengths = numel (unique (cellfun (@numel, y))) > 1; + all_vectors = all (cellfun ("isvector", y)); + different_lengths = numel (unique (cellfun ("numel", y))) > 1; if (all_vectors && different_lengths) [foobar(1:numel(y)).y] = ndgrid (y{:}); y = {foobar.y}; @@ -169,7 +169,7 @@ vi(idx) = extrapval; vi = reshape (vi, yshape); elseif (strcmp (method, "spline")) - if (any (! cellfun (@isvector, y))) + if (any (! cellfun ("isvector", y))) for i = 2 : nd if (! size_equal (y{1}, y{i})) error ("interpn: dimensional mismatch");
--- a/scripts/general/isa.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/isa.m Fri Aug 12 14:16:34 2011 -0400 @@ -75,3 +75,22 @@ %!assert (isa (uint16 (13), "numeric"), true) %!assert (isa (uint32 (13), "numeric"), true) %!assert (isa (uint64 (13), "numeric"), true) + +%!assert (isa (double (13), "double")); +%!assert (isa (single (13), "single")); +%!assert (isa (int8 (13), "int8")); +%!assert (isa (int16 (13), "int16")); +%!assert (isa (int32 (13), "int32")); +%!assert (isa (int64 (13), "int64")); +%!assert (isa (uint8 (13), "uint8")); +%!assert (isa (uint16 (13), "uint16")); +%!assert (isa (uint32 (13), "uint32")); +%!assert (isa (uint64 (13), "uint64")); +%!assert (isa ("string", "char")); +%!assert (isa (true, "logical")); +%!assert (isa (false, "logical")); +%!assert (isa ({1, 2}, "cell")); +%!test +%! a.b = 1; +%! assert (isa (a, "struct")); +
--- a/scripts/general/iscolumn.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/iscolumn.m Fri Aug 12 14:16:34 2011 -0400 @@ -26,8 +26,6 @@ function retval = iscolumn (x) - retval = false; - if (nargin != 1) print_usage (); endif
--- a/scripts/general/isdir.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/isdir.m Fri Aug 12 14:16:34 2011 -0400 @@ -23,10 +23,17 @@ ## @end deftypefn function retval = isdir (f) - if (nargin == 1) - ## Exist returns an integer but isdir should return a logical. - retval = (exist (f, "dir") == 7); - else + if (nargin != 1) print_usage ("isdir"); endif + + ## Exist returns an integer but isdir should return a logical. + retval = (exist (f, "dir") == 7); + endfunction + +%!error isdir (); +%!error isdir (1, 2); + +%!assert (isdir (pwd ())); +%!assert (! isdir ("this is highly unlikely to be a directory name"));
--- a/scripts/general/isequal.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/isequal.m Fri Aug 12 14:16:34 2011 -0400 @@ -24,12 +24,12 @@ function retval = isequal (x1, varargin) - if (nargin > 1) - retval = __isequal__ (false, x1, varargin{:}); - else + if (nargin < 2) print_usage (); endif + retval = __isequal__ (false, x1, varargin{:}); + endfunction ## test size and shape
--- a/scripts/general/isequalwithequalnans.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/isequalwithequalnans.m Fri Aug 12 14:16:34 2011 -0400 @@ -25,12 +25,12 @@ function retval = isequalwithequalnans (x1, varargin) - if (nargin > 1) - retval = __isequal__ (true, x1, varargin{:}); - else + if (nargin < 2) print_usage (); endif + retval = __isequal__ (true, x1, varargin{:}); + endfunction ## test for equality
--- a/scripts/general/isrow.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/isrow.m Fri Aug 12 14:16:34 2011 -0400 @@ -26,8 +26,6 @@ function retval = isrow (x) - retval = false; - if (nargin != 1) print_usage (); endif
--- a/scripts/general/isscalar.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/isscalar.m Fri Aug 12 14:16:34 2011 -0400 @@ -26,12 +26,12 @@ function retval = isscalar (x) - if (nargin == 1) - retval = numel (x) == 1; - else + if (nargin != 1) print_usage (); endif + retval = numel (x) == 1; + endfunction %!assert(isscalar (1));
--- a/scripts/general/issquare.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/issquare.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,42 +28,35 @@ function retval = issquare (x) - if (nargin == 1) - if (ndims (x) == 2) - [r, c] = size (x); - retval = r == c; - else - retval = false; - endif + if (nargin != 1) + print_usage (); + endif + + if (ndims (x) == 2) + [r, c] = size (x); + retval = r == c; else - print_usage (); + retval = false; endif endfunction +%!assert(issquare ([])); %!assert(issquare (1)); - %!assert(!(issquare ([1, 2]))); - -%!assert(issquare ([])); - %!assert(issquare ([1, 2; 3, 4])); - -%!test -%! assert(issquare ("t")); - +%!assert(!(issquare ([1, 2; 3, 4; 5, 6]))); +%!assert(!(issquare (ones (3,3,3)))); +%!assert(issquare ("t")); %!assert(!(issquare ("test"))); - -%!test -%! assert(issquare (["test"; "ing"; "1"; "2"])); - +%!assert(issquare (["test"; "ing"; "1"; "2"])); %!test %! s.a = 1; %! assert(issquare (s)); - -%!assert(!(issquare ([1, 2; 3, 4; 5, 6]))); +%!assert(issquare ({1, 2; 3, 4})); +%!assert(sparse (([1, 2; 3, 4]))); +%% Test input validation %!error issquare (); - %!error issquare ([1, 2; 3, 4], 2);
--- a/scripts/general/isvector.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/isvector.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,15 +28,13 @@ function retval = isvector (x) - retval = 0; - - if (nargin == 1) - sz = size (x); - retval = (ndims (x) == 2 && (sz(1) == 1 || sz(2) == 1)); - else + if (nargin != 1) print_usage (); endif + sz = size (x); + retval = (ndims (x) == 2 && (sz(1) == 1 || sz(2) == 1)); + endfunction %!assert(isvector (1));
--- a/scripts/general/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -61,6 +61,8 @@ general/polyarea.m \ general/postpad.m \ general/prepad.m \ + general/profile.m \ + general/profshow.m \ general/quadgk.m \ general/quadl.m \ general/quadv.m \
--- a/scripts/general/nargchk.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/nargchk.m Fri Aug 12 14:16:34 2011 -0400 @@ -30,16 +30,14 @@ ## Author: Bill Denney <bill@denney.ws> -function msg = nargchk (minargs, maxargs, nargs, outtype) +function msg = nargchk (minargs, maxargs, nargs, outtype = "string") if (nargin < 3 || nargin > 4) print_usage (); elseif (minargs > maxargs) error ("nargchk: MINARGS must be <= MAXARGS"); - elseif (nargin == 3) - outtype = "string"; elseif (! any (strcmpi (outtype, {"string", "struct"}))) - error ("nargchk: output type must be either string or struct"); + error ('nargchk: output type must be either "string" or "struct"'); elseif (! (isscalar (minargs) && isscalar (maxargs) && isscalar (nargs))) error ("nargchk: MINARGS, MAXARGS, and NARGS must be scalars"); endif @@ -56,13 +54,16 @@ if (strcmpi (outtype, "string")) msg = msg.message; elseif (isempty (msg.message)) - msg = struct ([]); + ## Compatability: Matlab returns a 0x1 empty struct when nargchk passes + msg = resize (msg, 0, 1); endif endfunction + ## Tests -%!shared stmin, stmax +%!shared stnul, stmin, stmax +%! stnul = resize (struct ("message", "", "identifier", ""), 0, 1); %! stmin = struct ("message", "not enough input arguments", %! "identifier", "Octave:nargchk:not-enough-inputs"); %! stmax = struct ("message", "too many input arguments", @@ -73,7 +74,7 @@ %!assert (nargchk (0, 1, 2), "too many input arguments") %!assert (nargchk (0, 1, 2, "string"), "too many input arguments") ## Struct outputs -%!assert (nargchk (0, 1, 0, "struct"), struct([])) -%!assert (nargchk (0, 1, 1, "struct"), struct([])) +%!assert (isequal (nargchk (0, 1, 0, "struct"), stnul)) +%!assert (isequal (nargchk (0, 1, 1, "struct"), stnul)) %!assert (nargchk (1, 1, 0, "struct"), stmin) %!assert (nargchk (0, 1, 2, "struct"), stmax)
--- a/scripts/general/nargoutchk.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/nargoutchk.m Fri Aug 12 14:16:34 2011 -0400 @@ -55,19 +55,17 @@ if (strcmpi (outtype, "string")) msg = msg.message; - else - if (isempty (msg.message)) - msg = struct ([]); - endif - ## FIXME: remove the error below if error is modified to accept - ## struct inputs - error ("nargoutchk: error does not yet support struct inputs"); + elseif (isempty (msg.message)) + ## Compatability: Matlab returns a 0x1 empty struct when nargchk passes + msg = resize (msg, 0, 1); endif endfunction + ## Tests -%!shared stmin, stmax +%!shared stnul, stmin, stmax +%! stnul = resize (struct ("message", "", "identifier", ""), 0, 1); %! stmin = struct ("message", "not enough output arguments", %! "identifier", "Octave:nargoutchk:not-enough-outputs"); %! stmax = struct ("message", "too many output arguments", @@ -78,7 +76,8 @@ %!assert (nargoutchk (0, 1, 2), "too many output arguments") %!assert (nargoutchk (0, 1, 2, "string"), "too many output arguments") ## Struct outputs -#%!assert (nargoutchk (0, 1, 0, "struct"), struct([])) -#%!assert (nargoutchk (0, 1, 1, "struct"), struct([])) -#%!assert (nargoutchk (1, 1, 0, "struct"), stmin) -#%!assert (nargoutchk (0, 1, 2, "struct"), stmax) +%!assert (isequal (nargoutchk (0, 1, 0, "struct"), stnul)) +%!assert (isequal (nargoutchk (0, 1, 1, "struct"), stnul)) +%!assert (nargoutchk (1, 1, 0, "struct"), stmin) +%!assert (nargoutchk (0, 1, 2, "struct"), stmax) +
--- a/scripts/general/nextpow2.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/nextpow2.m Fri Aug 12 14:16:34 2011 -0400 @@ -55,3 +55,14 @@ endif endfunction + +%!error nexpow2 (); +%!error nexpow2 (1, 2); + +%!assert (nextpow2 (16), 4); +%!assert (nextpow2 (17), 5); +%!assert (nextpow2 (31), 5); +%!assert (nextpow2 (-16), 4); +%!assert (nextpow2 (-17), 5); +%!assert (nextpow2 (-31), 5); +%!assert (nextpow2 (1:17), 5);
--- a/scripts/general/num2str.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/num2str.m Fri Aug 12 14:16:34 2011 -0400 @@ -111,10 +111,7 @@ nd = ndims (x); perm = fix ([1:0.5:nc+0.5]); perm(2:2:2*nc) = perm(2:2:2*nc) + nc; - idx = cell (); - for i = 1:nd - idx{i} = 1:sz(i); - endfor + idx = repmat ({':'}, nd, 1); idx{2} = perm; x = horzcat (real (x), imag (x)); x = x(idx{:});
--- a/scripts/general/postpad.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/postpad.m Fri Aug 12 14:16:34 2011 -0400 @@ -53,11 +53,8 @@ nd = ndims (x); sz = size (x); if (nargin < 4) - ## Find the first non-singleton dimension - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + ## Find the first non-singleton dimension. + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -76,10 +73,7 @@ d = sz (dim); if (d >= l) - idx = cell (); - for i = 1:nd - idx{i} = 1:sz(i); - endfor + idx = repmat ({':'}, nd, 1); idx{dim} = 1:l; y = x(idx{:}); else @@ -88,3 +82,16 @@ endif endfunction + +%!error postpad (); +%!error postpad (1); +%!error postpad (1,2,3,4,5); +%!error postpad ([1,2], 2, 2,3); + +%!assert (postpad ([1,2], 4), [1,2,0,0]); +%!assert (postpad ([1;2], 4), [1;2;0;0]); + +%!assert (postpad ([1,2], 4, 2), [1,2,2,2]); +%!assert (postpad ([1;2], 4, 2), [1;2;2;2]); + +%!assert (postpad ([1,2], 2, 2, 1), [1,2;2,2]);
--- a/scripts/general/prepad.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/prepad.m Fri Aug 12 14:16:34 2011 -0400 @@ -53,11 +53,8 @@ nd = ndims (x); sz = size (x); if (nargin < 4) - ## Find the first non-singleton dimension - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + ## Find the first non-singleton dimension. + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -76,10 +73,7 @@ d = sz (dim); if (d >= l) - idx = cell (); - for i = 1:nd - idx{i} = 1:sz(i); - endfor + idx = repmat ({':'}, nd, 1); idx{dim} = d-l+1:d; y = x(idx{:}); else @@ -88,3 +82,18 @@ endif endfunction + +%!error prepad (); +%!error prepad (1); +%!error prepad (1,2,3,4,5); +%!error prepad ([1,2], 2, 2,3); + +%!assert (prepad ([1,2], 4), [0,0,1,2]); +%!assert (prepad ([1;2], 4), [0;0;1;2]); + +%!assert (prepad ([1,2], 4, 2), [2,2,1,2]); +%!assert (prepad ([1;2], 4, 2), [2;2;1;2]); + +%!assert (prepad ([1,2], 2, 2, 1), [2,2;1,2]); + +## FIXME -- we need tests for multidimensional arrays.
--- a/scripts/general/private/__isequal__.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/private/__isequal__.m Fri Aug 12 14:16:34 2011 -0400 @@ -59,16 +59,16 @@ ## All arguments must either be of the same class or they must be ## numeric values. t = (all (strcmp (class(x), - cellfun (@class, varargin, "uniformoutput", false))) + cellfun ("class", varargin, "uniformoutput", false))) || ((isnumeric (x) || islogical (x)) - && all (cellfun (@isnumeric, varargin) - | cellfun (@islogical, varargin)))); + && all (cellfun ("isnumeric", varargin) + | cellfun ("islogical", varargin)))); if (t) ## Test that everything has the same number of dimensions. s_x = size (x); s_v = cellfun (@size, varargin, "uniformoutput", false); - t = all (length (s_x) == cellfun (@length, s_v)); + t = all (length (s_x) == cellfun ("length", s_v)); endif if (t) @@ -96,8 +96,8 @@ ## Test the number of fields. fn_x = fieldnames (x); l_fn_x = length (fn_x); - fn_v = cellfun (@fieldnames, varargin, "uniformoutput", false); - t = all (l_fn_x == cellfun (@length, fn_v)); + fn_v = cellfun ("fieldnames", varargin, "uniformoutput", false); + t = all (l_fn_x == cellfun ("length", fn_v)); ## Test that all the names are equal. idx = 0; @@ -146,7 +146,7 @@ elseif (isa (x, "function_handle")) ## The == operator is overloaded for handles. - t = all (cellfun (@eq, {x}, varargin)); + t = all (cellfun ("eq", {x}, varargin)); else ## Check the numeric types.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/general/profile.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,111 @@ +## Copyright (C) 2011 Daniel Kraft +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} profile on +## @deftypefnx {Function File} {} profile off +## @deftypefnx {Function File} {} profile resume +## @deftypefnx {Function File} {} profile clear +## @deftypefnx {Function File} {@var{S} =} profile ('status') +## @deftypefnx {Function File} {@var{T} =} profile ('info') +## Control the built-in profiler. +## +## @table @code +## @item profile on +## Start the profiler, clearing all previously collected data if there +## is any. +## +## @item profile off +## Stop profiling. The collected data can later be retrieved and examined +## with calls like @code{S = profile ('info')}. +## +## @item profile clear +## Clear all collected profiler data. +## +## @item profile resume +## Restart profiling without cleaning up the old data and instead +## all newly collected statistics are added to the already existing ones. +## +## @item @var{S} = profile ('status') +## Return a structure filled with certain information about the current status +## of the profiler. At the moment, the only field is @code{ProfilerStatus} +## which is either 'on' or 'off'. +## +## @item @var{T} = profile ('info') +## Return the collected profiling statistics in the structure @var{T}. +## Currently, the only field is @code{FunctionTable} which is an array +## of structures, each entry corresponding to a function which was called +## and for which profiling statistics are present. +## @end table +## @end deftypefn + +## Built-in profiler. +## Author: Daniel Kraft <d@domob.eu> + +function retval = profile (option) + + if (nargin != 1) + print_usage (); + endif + + switch (option) + case 'on' + __profiler_reset__ (); + __profiler_enable__ (true); + + case 'off' + __profiler_enable__ (false); + + case 'clear' + __profiler_reset__ (); + + case 'resume' + __profiler_enable__ (true); + + case 'status' + enabled = __profiler_enable__ (); + if (enabled) + enabled = 'on'; + else + enabled = 'off'; + endif + retval = struct ('ProfilerStatus', enabled); + + case 'info' + data = __profiler_data__ (); + retval = struct ('FunctionTable', data); + + otherwise + warning ("profile: Unrecognized option '%s'", option); + print_usage (); + + endswitch + +endfunction + + +%!demo +%! profile ('on'); +%! A = rand (100); +%! B = expm (A); +%! profile ('off'); +%! profile ('resume'); +%! C = sqrtm (A); +%! profile ('off'); +%! T = profile ('info'); +%! profshow (T);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/general/profshow.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,101 @@ +## Copyright (C) 2011 Daniel Kraft +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} profshow (@var{data}) +## @deftypefnx {Function File} {} profshow (@var{data}, @var{n}) +## Show flat profiler results. +## +## This command prints out profiler data as a flat profile. @var{data} is the +## structure returned by @code{profile ('info')}. If @var{n} is given, it +## specifies the number of functions to show in the profile; functions are +## sorted in descending order by total time spent in them. If there are more +## than @var{n} included in the profile, those will not be shown. @var{n} +## defaults to 20. +## +## The attribute column shows @samp{R} for recursive functions and nothing +## otherwise. +## @end deftypefn + +## Built-in profiler. +## Author: Daniel Kraft <d@domob.eu> + +function profshow (data, n = 20) + + if (nargin < 1 || nargin > 2) + print_usage (); + endif + + n = fix (n); + if (! isscalar (n) || ! isreal (n) || ! (n > 0)) + error ("profile: N must be a positive integer"); + endif + + m = length (data.FunctionTable); + n = min (n, m); + + ## We want to sort by times in descending order. For this, extract the + ## times to an array, then sort this, and use the resulting index permutation + ## to print out our table. + times = -[ data.FunctionTable.TotalTime ]; + + [~, p] = sort (times); + + ## For printing the table, find out the maximum length of a function name + ## so that we can proportion the table accordingly. Based on this, + ## we can build the format used for printing table rows. + nameLen = length ("Function"); + for i = 1 : n + nameLen = max (nameLen, length (data.FunctionTable(p(i)).FunctionName)); + endfor + headerFormat = sprintf ("%%%ds %%4s %%12s %%12s\n", nameLen); + rowFormat = sprintf ("%%%ds %%4s %%12.3f %%12d\n", nameLen); + + printf (headerFormat, "Function", "Attr", "Time (s)", "Calls"); + printf ("%s\n", repmat ("-", 1, nameLen + 2 * 13 + 5)); + for i = 1 : n + row = data.FunctionTable(p(i)); + attr = ""; + if (row.IsRecursive) + attr = "R"; + endif + printf (rowFormat, row.FunctionName, attr, row.TotalTime, row.NumCalls); + endfor + +endfunction + +%!demo +%! profile ("on"); +%! A = rand (100); +%! B = expm (A); +%! profile ("off"); +%! T = profile ("info"); +%! profshow (T, 10); + +%!demo +%! function f = myfib (n) +%! if (n <= 2) +%! f = 1; +%! else +%! f = myfib (n - 1) + myfib (n - 2); +%! endif +%! endfunction +%! profile ("on"); +%! myfib (20); +%! profile ("off"); +%! profshow (profile ("info"), 5);
--- a/scripts/general/quadl.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/quadl.m Fri Aug 12 14:16:34 2011 -0400 @@ -194,3 +194,25 @@ w = v; endif endfunction + + +## basic functionality +%!assert( quadl (@(x) sin (x), 0, pi, [], []), 2, -3e-16) + +## the values here are very high so it may be unavoidable that this fails +%!assert ( quadl (@(x) sin (3*x).*cosh (x).*sinh (x),10,15), +%! 2.588424538641647e+10, -9e-15) + +## extra parameters +%!assert (quadl (@(x,a,b) sin (a + b*x), 0, 1, [], [], 2, 3), +%! cos(2)/3 - cos(5)/3, - 3e-16) + +## test different tolerances. This test currently fails for a very high +## tolerances. +%!assert ( quadl (@(x) sin (2 + 3*x).^2, 0, 10, 0.3, []), +%! (60 + sin(4) - sin(64))/12, -0.3) + + +## for lower tolerances the test passes. +%!assert ( quadl (@(x) sin (2 + 3*x).^2, 0, 10, 0.1, []), +%! (60 + sin(4) - sin(64))/12, -0.1) \ No newline at end of file
--- a/scripts/general/rat.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/rat.m Fri Aug 12 14:16:34 2011 -0400 @@ -150,3 +150,11 @@ endif endfunction + +%!error rat (); +%!error rat (1, 2, 3); + +%!test +%! [n, d] = rat ([0.5, 0.3, 1/3]); +%! assert (n, [1, 3, 1]); +%! assert (d, [2, 10, 3]);
--- a/scripts/general/rot90.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/rot90.m Fri Aug 12 14:16:34 2011 -0400 @@ -52,44 +52,41 @@ ## Author: jwe -function B = rot90 (A, k) - - if (nargin == 1 || nargin == 2) - if (nargin < 2) - k = 1; - endif - - if (ndims (A) > 2) - error ("rot90: Only works with 2-D arrays"); - endif - - if (imag (k) != 0 || fix (k) != k) - error ("rot90: K must be an integer"); - endif - - k = rem (k, 4); +function B = rot90 (A, k = 1) - if (k < 0) - k = k + 4; - endif - - if (k == 0) - B = A; - elseif (k == 1) - B = flipud (A.'); - elseif (k == 2) - B = flipud (fliplr (A)); - elseif (k == 3) - B = (flipud (A)).'; - else - error ("rot90: internal error!"); - endif - else + if (nargin < 1 || nargin > 2) print_usage (); endif + if (ndims (A) > 2) + error ("rot90: A must be a 2-D array"); + endif + + if (! (isscalar (k) && isreal (k) && fix (k) == k)) + error ("rot90: K must be a single real integer"); + endif + + k = rem (k, 4); + + if (k < 0) + k = k + 4; + endif + + if (k == 0) + B = A; + elseif (k == 1) + B = flipud (A.'); + elseif (k == 2) + B = flipud (fliplr (A)); + elseif (k == 3) + B = (flipud (A)).'; + else + error ("rot90: internal error!"); + endif + endfunction + %!test %! x1 = [1, 2; 3, 4]; %! x2 = [2, 4; 1, 3]; @@ -106,4 +103,6 @@ %% Test input validation %!error rot90 (); %!error rot90 (1, 2, 3); - +%!error rot90 (1, ones(2)); +%!error rot90 (1, 1.5); +%!error rot90 (1, 1+i);
--- a/scripts/general/rotdim.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/rotdim.m Fri Aug 12 14:16:34 2011 -0400 @@ -71,22 +71,26 @@ nd = ndims (x); sz = size (x); if (nargin < 3) - ## Find the first two non-singleton dimension. - plane = []; - dim = 0; - while (dim < nd) - dim = dim + 1; - if (sz (dim) != 1) - plane = [plane, dim]; - if (length (plane) == 2) - break; + if (nd > 2) + ## Find the first two non-singleton dimension. + plane = []; + dim = 0; + while (dim < nd) + dim = dim + 1; + if (sz (dim) != 1) + plane = [plane, dim]; + if (length (plane) == 2) + break; + endif endif + endwhile + if (length (plane) < 1) + plane = [1, 2]; + elseif (length (plane) < 2) + plane = [1, plane]; endif - endwhile - if (length (plane) < 1) + else plane = [1, 2]; - elseif (length (plane) < 2) - plane = [1, plane]; endif else if (! (isvector (plane) && length (plane) == 2 @@ -119,3 +123,36 @@ endif endfunction + +%!error rotdim (); +%!error rotdim (1, 2, 3, 4); + +%!shared r, rr +%! r = [1,2,3]; rr = [3,2,1]; +%!assert (rotdim (r, 0), r); +%!assert (rotdim (r, 1), rr'); +%!assert (rotdim (r, 2), rr); +%!assert (rotdim (r, 3), r'); +%!assert (rotdim (r, 3), rotdim (r, -1)); +%!assert (rotdim (r, 1), rotdim (r)); + +%!shared c, cr +%! c = [1;2;3]; cr = [3;2;1]; +%!assert (rotdim (c, 0), c); +%!assert (rotdim (c, 1), c'); +%!assert (rotdim (c, 2), cr); +%!assert (rotdim (c, 3), cr'); +%!assert (rotdim (c, 3), rotdim (c, -1)); +%!assert (rotdim (c, 1), rotdim (c)); + +%!shared m +%! m = [1,2;3,4]; +%!assert (rotdim (m, 0), m); +%!assert (rotdim (m, 1), [2,4;1,3]); +%!assert (rotdim (m, 2), [4,3;2,1]); +%!assert (rotdim (m, 3), [3,1;4,2]); +%!assert (rotdim (m, 3), rotdim (m, -1)); +%!assert (rotdim (m, 1), rotdim (m)); + +## FIXME -- we need tests for multidimensional arrays and different +## values of PLANE.
--- a/scripts/general/shift.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/shift.m Fri Aug 12 14:16:34 2011 -0400 @@ -51,10 +51,7 @@ endif else ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); endif if (numel (x) < 1) @@ -63,10 +60,7 @@ d = sz (dim); - idx = cell (); - for i = 1:nd - idx{i} = 1:sz(i); - endfor + idx = repmat ({':'}, nd, 1); if (b >= 0) b = rem (b, d); idx{dim} = [d-b+1:d, 1:d-b];
--- a/scripts/general/shiftdim.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/shiftdim.m Fri Aug 12 14:16:34 2011 -0400 @@ -57,14 +57,9 @@ orig_dims = size (x); if (nargin == 1) - ## Find the first singleton dimension. - n = 0; - while (n < nd && orig_dims(n+1) == 1) - n++; - endwhile - endif - - if (! isscalar (n) || floor (n) != n) + ## Find the first non-singleton dimension. + (n = find (orig_dims != 1, 1) - 1) || (n = nd); + elseif (! (isscalar (n) && n == fix (n))) error ("shiftdim: N must be a scalar integer"); endif @@ -78,7 +73,7 @@ elseif (n > 0) ## We need permute here instead of reshape to shift values in a ## compatible way. - y = permute (x, [n+1:ndims(x) 1:n]); + y = permute (x, [n+1:nd 1:n]); else y = x; endif @@ -86,3 +81,20 @@ ns = n; endfunction + + +%!test +%! x = rand (1, 1, 4, 2); +%! [y, ns] = shiftdim (x); +%! assert (size (y), [4 2]); +%! assert (ns, 2); +%! assert (shiftdim (y, -2), x); +%! assert (size (shiftdim (x, 2)), [4 2]); +%!assert (size (shiftdim (rand (0, 1, 2))), [0 1 2]); + +%% Test input validation +%!error(shiftdim ()); +%!error(shiftdim (1,2,3)); +%!error(shiftdim (1, ones (2))); +%!error(shiftdim (1, 1.5)); +
--- a/scripts/general/structfun.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/structfun.m Fri Aug 12 14:16:34 2011 -0400 @@ -106,7 +106,7 @@ [varargout{:}] = cellfun (func, struct2cell (S), varargin{:}); if (! uniform_output) - varargout = cellfun (@cell2struct, varargout, {fieldnames(S)}, {1}, uo_str, false); + varargout = cellfun ("cell2struct", varargout, {fieldnames(S)}, {1}, uo_str, false); endif endfunction
--- a/scripts/general/triplequad.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/general/triplequad.m Fri Aug 12 14:16:34 2011 -0400 @@ -37,22 +37,25 @@ ## ## The optional argument @var{quadf} specifies which underlying integrator ## function to use. Any choice but @code{quad} is available and the default -## is @code{quadgk}. +## is @code{quadcc}. ## ## Additional arguments, are passed directly to @var{f}. To use the default -## value for @var{tol} or @var{quadf} one may pass an empty matrix ([]). +## value for @var{tol} or @var{quadf} one may pass ':' or an empty matrix ([]). ## @seealso{dblquad, quad, quadv, quadl, quadgk, quadcc, trapz} ## @end deftypefn -function q = triplequad(f, xa, xb, ya, yb, za, zb, tol, quadf, varargin) +function q = triplequad (f, xa, xb, ya, yb, za, zb, tol = 1e-6, quadf = @quadcc, varargin) + if (nargin < 7) print_usage (); endif - if (nargin < 8 || isempty (tol)) + + ## Allow use of empty matrix ([]) to indicate default + if (isempty (tol)) tol = 1e-6; endif - if (nargin < 9 || isempty (quadf)) - quadf = @quadgk; + if (isempty (quadf)) + quadf = @quadcc; endif inner = @__triplequad_inner__; @@ -61,7 +64,8 @@ varargin = {}; endif - q = dblquad(@(y, z) inner (y, z, f, xa, xb, tol, quadf, varargin{:}),ya, yb, za, zb, tol); + q = dblquad (@(y, z) inner (y, z, f, xa, xb, tol, quadf, varargin{:}), ya, yb, za, zb, tol); + endfunction function q = __triplequad_inner__ (y, z, f, xa, xb, tol, quadf, varargin) @@ -71,8 +75,11 @@ endfor endfunction -%% These tests are too expensive to run normally. Disable them -% !#assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [], @quadgk), pi ^ (3/2) * erf(1).^3, 1e-6) -% !#assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [], @quadl), pi ^ (3/2) * erf(1).^3, 1e-6) -% !#assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [], @quadv), pi ^ (3/2) * erf(1).^3, 1e-6) + +%!assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [], @quadcc), pi ^ (3/2) * erf(1).^3, 1e-6) +%% These tests are too expensive to run normally (~30 sec each). Disable them +#%!assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [], @quadgk), pi ^ (3/2) * erf(1).^3, 1e-6) +#%!#assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [], @quadl), pi ^ (3/2) * erf(1).^3, 1e-6) +#%!#assert (triplequad (@(x,y,z) exp(-x.^2 - y.^2 - z.^2) , -1, 1, -1, 1, -1, 1, [], @quadv), pi ^ (3/2) * erf(1).^3, 1e-6) +
--- a/scripts/geometry/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/geometry/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -12,9 +12,6 @@ geometry/griddatan.m \ geometry/inpolygon.m \ geometry/rectint.m \ - geometry/trimesh.m \ - geometry/triplot.m \ - geometry/trisurf.m \ geometry/tsearchn.m \ geometry/voronoi.m \ geometry/voronoin.m
--- a/scripts/geometry/trimesh.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -## Copyright (C) 2007-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} trimesh (@var{tri}, @var{x}, @var{y}, @var{z}) -## @deftypefnx {Function File} {@var{h} =} trimesh (@dots{}) -## Plot a triangular mesh in 3D@. The variable @var{tri} is the triangular -## meshing of the points @code{(@var{x}, @var{y})} which is returned -## from @code{delaunay}. The variable @var{z} is value at the point -## @code{(@var{x}, @var{y})}. The output argument @var{h} is the graphic -## handle of the plot. -## @seealso{triplot, trisurf, delaunay3} -## @end deftypefn - -function h = trimesh (tri, x, y, z, varargin) - - if (nargin < 3) - print_usage (); - endif - - if (nargin == 3) - triplot (tri, x, y); - elseif (ischar (z)) - triplot (tri, x, y, z, varargin{:}); - else - newplot (); - if (nargout > 0) - h = patch ("Vertices", [x(:), y(:), z(:)], "Faces", tri, - "FaceColor", "none", "EdgeColor", __next_line_color__(), - varargin{:}); - else - patch ("Vertices", [x(:), y(:), z(:)], "Faces", tri, - "FaceColor", "none", "EdgeColor", __next_line_color__(), - varargin{:}); - endif - - if (! ishold ()) - set (gca(), "view", [-37.5, 30], - "xgrid", "on", "ygrid", "on", "zgrid", "on"); - endif - endif -endfunction - -%!demo -%! N = 10; -%! rand ('state', 10) -%! x = 3 - 6 * rand (N, N); -%! y = 3 - 6 * rand (N, N); -%! z = peaks (x, y); -%! tri = delaunay (x(:), y(:)); -%! trimesh (tri, x(:), y(:), z(:));
--- a/scripts/geometry/triplot.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,53 +0,0 @@ -## Copyright (C) 2007-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} triplot (@var{tri}, @var{x}, @var{y}) -## @deftypefnx {Function File} {} triplot (@var{tri}, @var{x}, @var{y}, @var{linespec}) -## @deftypefnx {Function File} {@var{h} =} triplot (@dots{}) -## Plot a triangular mesh in 2D@. The variable @var{tri} is the triangular -## meshing of the points @code{(@var{x}, @var{y})} which is returned from -## @code{delaunay}. If given, the @var{linespec} determines the properties -## to use for the lines. The output argument @var{h} is the graphic handle -## of the plot. -## @seealso{plot, trimesh, trisurf, delaunay} -## @end deftypefn - -function h = triplot (tri, x, y, varargin) - - if (nargin < 3) - print_usage (); - endif - - idx = tri(:, [1, 2, 3, 1]).'; - nt = size (tri, 1); - if (nargout > 0) - h = plot ([x(idx); NaN(1, nt)](:), - [y(idx); NaN(1, nt)](:), varargin{:}); - else - plot ([x(idx); NaN(1, nt)](:), - [y(idx); NaN(1, nt)](:), varargin{:}); - endif -endfunction - -%!demo -%! rand ('state', 2) -%! x = rand (20, 1); -%! y = rand (20, 1); -%! tri = delaunay (x, y); -%! triplot (tri, x, y);
--- a/scripts/geometry/trisurf.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -## Copyright (C) 2007-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} trisurf (@var{tri}, @var{x}, @var{y}, @var{z}) -## @deftypefnx {Function File} {@var{h} =} trisurf (@dots{}) -## Plot a triangular surface in 3D@. The variable @var{tri} is the triangular -## meshing of the points @code{(@var{x}, @var{y})} which is returned -## from @code{delaunay}. The variable @var{z} is value at the point -## @code{(@var{x}, @var{y})}. The output argument @var{h} is the graphic -## handle of the plot. -## @seealso{triplot, trimesh, delaunay3} -## @end deftypefn - -function varargout = trisurf (tri, x, y, z, varargin) - - if (nargin < 3) - print_usage (); - endif - - if (nargin == 3) - triplot (tri, x, y); - elseif (ischar (z)) - triplot (tri, x, y, z, varargin{:}); - else - if (nargin > 4 && isnumeric (varargin{1})) - c = varargin{1}; - varargin(1) = []; - else - c = z; - endif - if (! any (strcmpi (varargin, "FaceColor"))) - nfc = numel (varargin) + 1; - varargin(nfc+(0:1)) = {"FaceColor", "flat"}; - else - nfc = find (any (strcmpi (varargin, "FaceColor")), 1); - endif - if (! any (strcmpi (varargin, "EdgeColor")) - && strcmpi (varargin{nfc+1}, "interp")) - varargin(end+(1:2)) = {"EdgeColor", "none"}; - endif - newplot (); - h = patch ("Faces", tri, "Vertices", [x(:), y(:), z(:)], - "FaceVertexCData", reshape (c, numel (c), 1), - varargin{:}); - if (nargout > 0) - varargout = {h}; - endif - - if (! ishold ()) - set (gca(), "view", [-37.5, 30], - "xgrid", "on", "ygrid", "on", "zgrid", "on"); - endif - endif -endfunction - -%!demo -%! N = 10; -%! rand ('state', 10) -%! x = 3 - 6 * rand (N, N); -%! y = 3 - 6 * rand (N, N); -%! z = peaks (x, y); -%! tri = delaunay (x(:), y(:)); -%! trisurf (tri, x(:), y(:), z(:)); - -%!demo -%! x = rand (100, 1); -%! y = rand (100, 1); -%! z = x.^2 + y.^2; -%! tri = delaunay (x, y); -%! trisurf (tri, x, y, z) - -%!demo -%! x = rand (100, 1); -%! y = rand (100, 1); -%! z = x.^2 + y.^2; -%! tri = delaunay (x, y); -%! trisurf (tri, x, y, z, "facecolor", "interp") - -%!demo -%! x = rand (100, 1); -%! y = rand (100, 1); -%! z = x.^2 + y.^2; -%! tri = delaunay (x, y); -%! trisurf (tri, x, y, z, "facecolor", "interp", "edgecolor", "k") - -
--- a/scripts/geometry/voronoi.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/geometry/voronoi.m Fri Aug 12 14:16:34 2011 -0400 @@ -129,7 +129,7 @@ idx = find (!infi); ll = length (idx); c = c(idx).'; - k = sum (cellfun ('length', c)); + k = sum (cellfun ("length", c)); edges = cell2mat(cellfun (@(x) [x ; [x(end), x(1:end-1)]], c, "uniformoutput", false)); @@ -166,3 +166,13 @@ endif endfunction + +%!testif HAVE_QHULL +%! phi=linspace(-pi,3/4*pi,8); +%! [x,y]=pol2cart(phi,1); +%! [vx,vy]=voronoi(x,y); +%! assert(vx(2,:),zeros(1,size(vx,2)),eps); +%! assert(vy(2,:),zeros(1,size(vy,2)),eps); + +%!demo +%! voronoi (rand(10,1), rand(10,1));
--- a/scripts/help/__makeinfo__.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/help/__makeinfo__.m Fri Aug 12 14:16:34 2011 -0400 @@ -17,8 +17,8 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {[@var{retval}, @var{status}] =} __makeinfo__ (@var{text}, @var{output_type}) -## @deftypefnx {Function File} {[@var{retval}, @var{status}] =} __makeinfo__ (@var{text}, @var{output_type}, @var{see_also}) +## @deftypefn {Function File} {[@var{retval}, @var{status}] =} __makeinfo__ (@var{text}) +## @deftypefnx {Function File} {[@var{retval}, @var{status}] =} __makeinfo__ (@var{text}, @var{output_type}) ## Undocumented internal function. ## @end deftypefn @@ -33,13 +33,6 @@ ## @t{"plain text"}. If @var{output_type} is @t{"texinfo"}, the @t{@@seealso} ## macro is expanded, but otherwise the text is unaltered. ## -## If the optional argument @var{see_also} is present, it is used to expand the -## Octave specific @t{@@seealso} macro. This argument must be a function handle, -## that accepts a cell array of strings as input argument (each elements of the -## array corresponds to the arguments to the @t{@@seealso} macro), and return -## the expanded string. If this argument is not given, the @t{@@seealso} macro -## will be expanded to the text -## ## @example ## See also: arg1, arg2@, ... ## @end example @@ -60,7 +53,7 @@ function [retval, status] = __makeinfo__ (text, output_type = "plain text", see_also = []) ## Check input - if (nargin == 0) + if (nargin < 1 || nargin > 2) print_usage (); endif @@ -72,72 +65,18 @@ error ("__makeinfo__: second input argument must be a string"); endif - ## Define the function which expands @seealso macro - if (isempty (see_also)) - if (strcmpi (output_type, "plain text")) - see_also = @simple_see_also; - else - see_also = @simple_see_also_with_refs; - endif - endif - - if (!isa (see_also, "function_handle")) - error ("__makeinfo__: third input argument must be the empty matrix, or a function handle"); - endif - ## It seems like makeinfo sometimes gets angry if the first character ## on a line is a space, so we remove these. text = strrep (text, "\n ", "\n"); ## Handle @seealso macro - SEE_ALSO = "@seealso"; - starts = strfind (text, SEE_ALSO); - for start = fliplr (starts) - if (start == 1 || (text (start-1) != "@")) - bracket_start = find (text (start:end) == "{", 1); - stop = find (text (start:end) == "}", 1); - if (!isempty (stop) && !isempty (bracket_start)) - stop += start - 1; - bracket_start += start - 1; - else - bracket_start = start + length (SEE_ALSO); - stop = find (text (start:end) == "\n", 1); - if (isempty (stop)) - stop = length (text); - else - stop += start - 1; - endif - endif - see_also_args = text (bracket_start+1:(stop-1)); - see_also_args = strtrim (strsplit (see_also_args, ",")); - expanded = see_also (see_also_args); - text = strcat (text (1:start-1), expanded, text (stop+1:end)); - endif - endfor - + if (strcmpi (output_type, "plain text")) + text = regexprep (text, '@seealso *\{([^}]*)\}', "\nSee also: $1.\n\n"); + else + text = regexprep (text, '@seealso *\{([^}]*)\}', "\nSee also: @ref{$1}.\n\n"); + endif ## Handle @nospell macro - NOSPELL = "@nospell"; - starts = strfind (text, NOSPELL); - for start = fliplr (starts) - if (start == 1 || (text (start-1) != "@")) - bracket_start = find (text (start:end) == "{", 1); - stop = find (text (start:end) == "}", 1); - if (!isempty (stop) && !isempty (bracket_start)) - stop += start - 1; - bracket_start += start - 1; - else - bracket_start = start + length (NOSPELL); - stop = find (text (start:end) == "\n", 1); - if (isempty (stop)) - stop = length (text); - else - stop += start - 1; - endif - endif - text(stop) = []; - text(start:bracket_start) = []; - endif - endfor + text = regexprep (text, '@nospell *\{([^}]*)\}', "$1"); if (strcmpi (output_type, "texinfo")) status = 0; @@ -180,12 +119,3 @@ end_unwind_protect endfunction -function expanded = simple_see_also (args) - expanded = strcat ("\nSee also:", sprintf (" %s,", args {:})); - expanded = strcat (expanded (1:end-1), "\n\n"); -endfunction - -function expanded = simple_see_also_with_refs (args) - expanded = strcat ("\nSee also:", sprintf (" @ref{%s},", args {:})); - expanded = strcat (expanded (1:end-1), "\n\n"); -endfunction
--- a/scripts/help/__strip_html_tags__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,81 +0,0 @@ -## Copyright (C) 2009-2011 Søren Hauberg -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{text}, @var{status}] =} __strip_html_tags__ (@var{html_text}) -## Undocumented internal function. -## @end deftypefn - -## Remove HTML tags from text. This is used as a simple HTML-to-text -## function. - -function [text, status] = __strip_html_tags__ (html_text) - start = find (html_text == "<"); - stop = find (html_text == ">"); - if (length (start) == length (stop)) - text = html_text; - for n = length(start):-1:1 - text (start (n):stop (n)) = []; - endfor - text = strip_superfluous_endlines (text); - status = 0; - else - warning ("help: invalid HTML data -- raw HTML source follows..."); - disp (html_text); - text = ""; - status = 1; - endif -endfunction - -## This function removes end-lines (\n) that makes printing look bad -function text = strip_superfluous_endlines (text) - ## Find groups of end-lines - els = find (text == "\n"); - dels = diff (els); - groups = [els(1), 1]; # list containing [start, length] of each group - for k = 1:length (dels) - if (dels (k) == 1) - groups (end, 2) ++; - else - groups (end+1, 1:2) = [els(k+1), 1]; - endif - endfor - - keep = true (size (text)); - - ## Remove end-lines in the beginning - if (groups (1, 1) == 1) - keep (1:groups (1, 2)) = false; - endif - - ## Remove end-lines from the end - if (sum (groups (end, :)) - 1 == length (text)) - keep (groups (end, 1):end) = false; - endif - - ## Remove groups of end-lines with more than 3 end-lines next to each other - idx = find (groups (:, 2) >= 3); - for k = 1:length (idx) - start = groups (idx (k), 1); - stop = start + groups (idx (k), 2) - 1; - keep (start+2:stop) = false; - endfor - - ## Actually remove the elements - text = text (keep); -endfunction
--- a/scripts/help/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/help/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -1,11 +1,11 @@ FCN_FILE_DIRS += help help_PRIVATE_FCN_FILES = \ - help/private/__additional_help_message__.m + help/private/__additional_help_message__.m \ + help/private/__strip_html_tags__.m help_FCN_FILES = \ help/__makeinfo__.m \ - help/__strip_html_tags__.m \ help/doc.m \ help/gen_doc_cache.m \ help/get_first_help_sentence.m \ @@ -13,6 +13,7 @@ help/lookfor.m \ help/print_usage.m \ help/type.m \ + help/unimplemented.m \ help/which.m \ $(help_PRIVATE_FCN_FILES)
--- a/scripts/help/print_usage.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/help/print_usage.m Fri Aug 12 14:16:34 2011 -0400 @@ -136,3 +136,7 @@ retval = get_usage_plain_text (help_text, max_len); endfunction + +## Stop reporting function as missing tests. No good tests possible. +%!assert (1) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/help/private/__strip_html_tags__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,81 @@ +## Copyright (C) 2009-2011 Søren Hauberg +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{text}, @var{status}] =} __strip_html_tags__ (@var{html_text}) +## Undocumented internal function. +## @end deftypefn + +## Remove HTML tags from text. This is used as a simple HTML-to-text +## function. + +function [text, status] = __strip_html_tags__ (html_text) + start = find (html_text == "<"); + stop = find (html_text == ">"); + if (length (start) == length (stop)) + text = html_text; + for n = length(start):-1:1 + text (start (n):stop (n)) = []; + endfor + text = strip_superfluous_endlines (text); + status = 0; + else + warning ("help: invalid HTML data -- raw HTML source follows..."); + disp (html_text); + text = ""; + status = 1; + endif +endfunction + +## This function removes end-lines (\n) that makes printing look bad +function text = strip_superfluous_endlines (text) + ## Find groups of end-lines + els = find (text == "\n"); + dels = diff (els); + groups = [els(1), 1]; # list containing [start, length] of each group + for k = 1:length (dels) + if (dels (k) == 1) + groups (end, 2) ++; + else + groups (end+1, 1:2) = [els(k+1), 1]; + endif + endfor + + keep = true (size (text)); + + ## Remove end-lines in the beginning + if (groups (1, 1) == 1) + keep (1:groups (1, 2)) = false; + endif + + ## Remove end-lines from the end + if (sum (groups (end, :)) - 1 == length (text)) + keep (groups (end, 1):end) = false; + endif + + ## Remove groups of end-lines with more than 3 end-lines next to each other + idx = find (groups (:, 2) >= 3); + for k = 1:length (idx) + start = groups (idx (k), 1); + stop = start + groups (idx (k), 2) - 1; + keep (start+2:stop) = false; + endfor + + ## Actually remove the elements + text = text (keep); +endfunction
--- a/scripts/help/type.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/help/type.m Fri Aug 12 14:16:34 2011 -0400 @@ -111,4 +111,14 @@ endfor endfunction +%!test +%! var = 1; +%! typestr = type ("var"); +%! typestr = typestr{1}(1:17); +%! assert (typestr, "var is a variable"); +%!assert (type ('dot'){1}, "dot is a dynamically-linked function") +%!assert (type ('cat'){1}, "cat is a built-in function") +%!assert (type ('+'){1}, "+ is an operator") +%!assert (type ('end'){1}, "end is a keyword") +%!error (type ('NO_NAME'))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/help/unimplemented.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,439 @@ +## Copyright (C) 2010-2011 John W. Eaton +## Copyright (C) 2010 VZLU Prague +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} unimplemented () +## Undocumented internal function. +## @end deftypefn + +function txt = unimplemented (fcn) + + is_matlab_function = true; + + ## Some smarter cases, add more as needed. + switch (fcn) + + case "quad2d" + txt = ["quad2d is not implemented. Consider using dblquad."]; + + case "gsvd" + txt = ["gsvd is not currently part of Octave. See the linear-algebra",... + "package at @url{http://octave.sf.net/linear-algebra/}."]; + + case "linprog" + txt = ["Octave does not currently provide linprog. ",... + "Linear programming problems may be solved using @code{glpk}. ",... + "Try @code{help glpk} for more info."]; + + case {"ode113", "ode15i", "ode15s", "ode23", "ode23s", "ode23t", "ode45", "odeget", "odeset"} + txt = ["Octave provides lsode for solving differential equations. ",... + "For more information try @code{help lsode}. ",... + "Matlab-compatible ODE functions are provided by the odepkg package. ",... + "See @url{http://octave.sf.net/odepkg/}."]; + + otherwise + if (ismember (fcn, missing_functions ())) + txt = sprintf ("the `%s' function is not yet implemented in Octave", fcn); + else + is_matlab_function = false; + txt = ""; + endif + endswitch + + if (is_matlab_function) + txt = [txt, "\n\n@noindent\nPlease read ",... + "@url{http://www.octave.org/missing.html} to learn how ",... + "you can contribute missing functionality."]; + txt = __makeinfo__ (txt); + endif + + if (nargout == 0) + warning ("Octave:missing-function", "%s", txt); + endif + +endfunction + +function list = missing_functions () + persistent list = { + "DelaunayTri", + "MException", + "RandStream", + "TriRep", + "TriScatteredInterp", + "addpref", + "align", + "alim", + "alpha", + "alphamap", + "annotation", + "audiodevinfo", + "audioplayer", + "audiorecorder", + "aufinfo", + "auread", + "auwrite", + "avifile", + "aviinfo", + "aviread", + "bar3", + "bar3h", + "bench", + "betaincinv", + "bicg", + "bicgstabl", + "brush", + "builddocsearchdb", + "bvp4c", + "bvp5c", + "bvpget", + "bvpinit", + "bvpset", + "bvpxtend", + "callSoapService", + "calllib", + "camdolly", + "cameratoolbar", + "camlight", + "camlookat", + "camorbit", + "campan", + "campos", + "camproj", + "camroll", + "camtarget", + "camup", + "camva", + "camzoom", + "cdf2rdf", + "cdfepoch", + "cdfinfo", + "cdfread", + "cdfwrite", + "cellplot", + "checkin", + "checkout", + "cholinc", + "clearvars", + "clipboard", + "cmopts", + "cmpermute", + "cmunique", + "colordef", + "colormapeditor", + "commandhistory", + "commandwindow", + "condeig", + "coneplot", + "contourslice", + "copyobj", + "createClassFromWsdl", + "createSoapMessage", + "customverctrl", + "daqread", + "datacursormode", + "datatipinfo", + "dbmex", + "dde23", + "ddeget", + "ddesd", + "ddeset", + "decic", + "depdir", + "depfun", + "deval", + "dialog", + "dither", + "docopt", + "docsearch", + "dragrect", + "dynamicprops", + "echodemo", + "ellipj", + "ellipke", + "erfcinv", + "errordlg", + "evalc", + "exifread", + "expint", + "export2wsdlg", + "figurepalette", + "filebrowser", + "fill3", + "findfigs", + "fitsinfo", + "fitsread", + "flow", + "fminsearch", + "frame2im", + "freqspace", + "funm", + "gallery", + "gammaincinv", + "gco", + "getframe", + "getpixelposition", + "getpref", + "gmres", + "grabcode", + "graymon", + "gsvd", + "guidata", + "guide", + "guihandles", + "handle", + "hdf", + "hdf5", + "hdf5info", + "hdf5read", + "hdf5write", + "hdfinfo", + "hdfread", + "hdftool", + "helpbrowser", + "helpdesk", + "helpdlg", + "helpwin", + "hgexport", + "hgload", + "hgsave", + "hgsetget", + "hgtransform", + "hostid", + "ilu", + "im2frame", + "im2java", + "imapprox", + "imformats", + "import", + "importdata", + "inmem", + "inputParser", + "inputdlg", + "inspect", + "instrfind", + "instrfindall", + "interpstreamspeed", + "iscom", + "isinterface", + "isjava", + "isocaps", + "ispref", + "isstudent", + "javaArray", + "javaMethod", + "javaMethodEDT", + "javaObject", + "javaObjectEDT", + "javaaddpath", + "javachk", + "javaclasspath", + "javarmpath", + "ldl", + "libfunctions", + "libfunctionsview", + "libisloaded", + "libpointer", + "libstruct", + "light", + "lightangle", + "lighting", + "linkaxes", + "linkdata", + "linsolve", + "listdlg", + "listfonts", + "loadlibrary", + "lscov", + "lsqr", + "makehgtform", + "material", + "matlabrc", + "maxNumCompThreads", + "memmapfile", + "memory", + "metaclass", + "methodsview", + "minres", + "mlint", + "mlintrpt", + "mmfileinfo", + "mmreader", + "movegui", + "movie", + "movie2avi", + "msgbox", + "multibandread", + "multibandwrite", + "native2unicode", + "noanimate", + "ode113", + "ode15i", + "ode15s", + "ode23", + "ode23s", + "ode23t", + "ode23tb", + "ode45", + "odefile", + "odeget", + "odeset", + "odextend", + "open", + "openfig", + "opengl", + "openvar", + "ordeig", + "ordqz", + "ordschur", + "padecoef", + "pagesetupdlg", + "pan", + "parseSoapResponse", + "path2rc", + "pathtool", + "pcode", + "pdepe", + "pdeval", + "playshow", + "plotbrowser", + "plotedit", + "plottools", + "polyeig", + "prefdir", + "preferences", + "printdlg", + "printopt", + "printpreview", + "profile", + "profsave", + "propedit", + "propertyeditor", + "publish", + "qmr", + "quad2d", + "questdlg", + "rbbox", + "recycle", + "reducepatch", + "reducevolume", + "resample", + "rgbplot", + "rmpref", + "root", + "rotate", + "rotate3d", + "selectmoveresize", + "sendmail", + "serial", + "setpixelposition", + "setpref", + "showplottool", + "shrinkfaces", + "smooth3", + "snapnow", + "sound", + "soundsc", + "ss2tf", + "stream2", + "stream3", + "streamline", + "streamparticles", + "streamribbon", + "streamslice", + "streamtube", + "strings", + "subvolume", + "superclasses", + "support", + "surf2patch", + "symmlq", + "syntax", + "tetramesh", + "texlabel", + "textwrap", + "tfqmr", + "timer", + "timerfind", + "timerfindall", + "timeseries", + "toolboxdir", + "tscollection", + "tstool", + "uibuttongroup", + "uicontextmenu", + "uicontrol", + "uigetpref", + "uiimport", + "uiopen", + "uipanel", + "uipushtool", + "uiresume", + "uisave", + "uisetcolor", + "uisetfont", + "uisetpref", + "uistack", + "uitable", + "uitoggletool", + "uitoolbar", + "uiwait", + "undocheckout", + "unicode2native", + "unloadlibrary", + "unmesh", + "usejava", + "userpath", + "validateattributes", + "verLessThan", + "viewmtx", + "visdiff", + "volumebounds", + "waitbar", + "waitfor", + "warndlg", + "waterfall", + "wavfinfo", + "wavplay", + "wavrecord", + "web", + "whatsnew", + "wk1finfo", + "wk1read", + "wk1write", + "workspace", + "xlsfinfo", + "xlsread", + "xlswrite", + "xmlread", + "xmlwrite", + "xslt", + "zoom", + }; +endfunction + + +%!test +%! str = unimplemented ("no_name_function"); +%! assert (isempty (str)); +%! str = unimplemented ("quad2d"); +%! assert (str(1:51), "quad2d is not implemented. Consider using dblquad."); +%! str = unimplemented ("MException"); +%! assert (str(1:58), "the `MException' function is not yet implemented in Octave"); + +
--- a/scripts/help/which.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/help/which.m Fri Aug 12 14:16:34 2011 -0400 @@ -53,3 +53,13 @@ endif endfunction + + +%!test +%! str = which ("ls"); +%! assert (str(end-17:end), strcat ("miscellaneous", filesep(), "ls.m")); +%!test +%! str = which ("dot"); +%! assert (str(end-6:end), "dot.oct"); + +%!assert (which ("NO_NAME"), "");
--- a/scripts/image/image.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/image/image.m Fri Aug 12 14:16:34 2011 -0400 @@ -19,9 +19,9 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} image (@var{img}) ## @deftypefnx {Function File} {} image (@var{x}, @var{y}, @var{img}) -## Display a matrix as a color image. The elements of @var{x} are indices +## Display a matrix as a color image. The elements of @var{img} are indices ## into the current colormap, and the colormap will be scaled so that the -## extremes of @var{x} are mapped to the extremes of the colormap. +## extremes of @var{img} are mapped to the extremes of the colormap. ## ## The axis values corresponding to the matrix elements are specified in ## @var{x} and @var{y}. If you're not using gnuplot 4.2 or later, these
--- a/scripts/io/strread.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/io/strread.m Fri Aug 12 14:16:34 2011 -0400 @@ -19,15 +19,16 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{a}, @dots{}] =} strread (@var{str}) ## @deftypefnx {Function File} {[@var{a}, @dots{}] =} strread (@var{str}, @var{format}) +## @deftypefnx {Function File} {[@var{a}, @dots{}] =} strread (@var{str}, @var{format}, @var{format_repeat}) ## @deftypefnx {Function File} {[@var{a}, @dots{}] =} strread (@var{str}, @var{format}, @var{prop1}, @var{value1}, @dots{}) +## @deftypefnx {Function File} {[@var{a}, @dots{}] =} strread (@var{str}, @var{format}, @var{format_repeat}, @var{prop1}, @var{value1}, @dots{}) ## Read data from a string. ## ## The string @var{str} is split into words that are repeatedly matched to the ## specifiers in @var{format}. The first word is matched to the first -## specifier, -## the second to the second specifier and so forth. If there are more words -## than -## specifiers, the process is repeated until all words have been processed. +## specifier, the second to the second specifier and so forth. If there are +## more words than specifiers, the process is repeated until all words have +## been processed. ## ## The string @var{format} describes how the words in @var{str} should be ## parsed. @@ -36,19 +37,31 @@ ## @item %s ## The word is parsed as a string. ## -## @item %d ## @itemx %f -## The word is parsed as a number. +## @itemx %n +## The word is parsed as a number and converted to double. +## +## @item %d +## @itemx %u +## The word is parsed as a number and converted to int32. ## -## @item %* +## @item %*', '%*f', '%*s ## The word is skipped. +## +## For %s and %d, %f, %n, %u and the associated %*s @dots{} specifiers an +## optional width can be specified as %Ns, etc. where N is an integer > 1. +## For %f, format specifiers like %N.Mf are allowed. +## +## @item literals +## In addition the format may contain literal character strings; these will be +## skipped during reading. ## @end table ## ## Parsed word corresponding to the first specifier are returned in the first ## output argument and likewise for the rest of the specifiers. ## ## By default, @var{format} is @t{"%f"}, meaning that numbers are read from -## @var{str}. +## @var{str}. This will do if @var{str} contains only numeric fields. ## ## For example, the string ## @@ -68,6 +81,18 @@ ## [@var{a}, @var{b}, @var{c}] = strread (@var{str}, "%s %s %f"); ## @end example ## +## Optional numeric argument @var{format_repeat} can be used for +## limiting the number of items read: +## @table @asis +## @item -1 +## (default) read all of the string until the end. +## +## @item N +## Read N times @var{nargout} items. 0 (zero) is an acceptable +## value for @var{format_repeat}. +## +## @end table +## ## The behavior of @code{strread} can be changed via property-value ## pairs. The following properties are recognized: ## @@ -77,94 +102,202 @@ ## @var{value} is the comment style and can be any of the following. ## @itemize ## @item "shell" -## Everything from @code{#} characters to the nearest end-line is skipped. +## Everything from @code{#} characters to the nearest end-of-line is skipped. ## ## @item "c" ## Everything between @code{/*} and @code{*/} is skipped. ## ## @item "c++" -## Everything from @code{//} characters to the nearest end-line is skipped. +## Everything from @code{//} characters to the nearest end-of-line is skipped. ## ## @item "matlab" -## Everything from @code{%} characters to the nearest end-line is skipped. +## Everything from @code{%} characters to the nearest end-of-line is skipped. +## +## @item user-supplied. Two options: +## (1) One string, or 1x1 cell string: Skip everything to the right of it; +## (2) 2x1 cell string array: Everything between the left and right strings +## is skipped. ## @end itemize ## ## @item "delimiter" -## Any character in @var{value} will be used to split @var{str} into words. +## Any character in @var{value} will be used to split @var{str} into words +## (default value = any whitespace). ## ## @item "emptyvalue" ## Parts of the output where no word is available is filled with @var{value}. +## +## @item "multipledelimsasone" +## Treat a series of consecutive delimiters, without whitespace in between, +## as a single delimiter. Consecutive delimiter series need not be vertically +## "aligned". +## +## @item "treatasempty" +## Treat single occurrences (surrounded by delimiters or whitespace) of the +## string(s) in @var{value} as missing values. +## +## @item "returnonerror" +## If @var{value} true (1, default), ignore read errors and return normally. +## If false (0), return an error. +## +## @item "whitespace" +## Any character in @var{value} will be interpreted as whitespace and +## trimmed; the string defining whitespace must be enclosed in double +## quotes for proper processing of special characters like \t. +## The default value for whitespace = " \b\r\n\t" (note the space). +## ## @end table ## -## @seealso{textread, load, dlmread, fscanf} +## @seealso{textscan, textread, load, dlmread, fscanf} ## @end deftypefn function varargout = strread (str, format = "%f", varargin) + ## Check input if (nargin < 1) print_usage (); endif - if (!ischar (str) || !ischar (format)) + if (isempty (format)) + format = "%f"; + endif + + if (! ischar (str) || ! ischar (format)) error ("strread: STR and FORMAT arguments must be strings"); endif - ## Parse options + ## Parse format string to compare number of conversion fields and nargout + nfields = length (strfind (format, "%")) - length (strfind (format, "%*")); + ## If str only has numeric fields, a (default) format ("%f") will do. + ## Otherwise: + if ((max (nargout, 1) != nfields) && ! strcmp (format, "%f")) + error ("strread: the number of output variables must match that specified by FORMAT"); + endif + + ## Check for format string repeat count + format_repeat_count = -1; + if (nargin > 2 && isnumeric (varargin{1})) + if (varargin{1} >= 0) + format_repeat_count = varargin{1}; + endif + if (nargin > 3) + varargin = varargin(2:end); + else + varargin = {}; + endif + endif + + ## Parse options. First initialize defaults comment_flag = false; - numeric_fill_value = 0; - white_spaces = " \n\r\t\b"; delimiter_str = ""; + empty_str = ""; + eol_char = ""; + err_action = 0; + mult_dlms_s1 = false; + numeric_fill_value = NaN; + white_spaces = " \b\r\n\t"; for n = 1:2:length (varargin) - switch (lower (varargin {n})) + switch (lower (varargin{n})) + case "bufsize" + ## We could synthesize this, but that just seems weird... + warning ('strread: property "bufsize" is not implemented'); case "commentstyle" comment_flag = true; - switch (lower (varargin {n+1})) + switch (lower (varargin{n+1})) case "c" - comment_specif = {"/*", "*/"}; + [comment_start, comment_end] = deal ("/*", "*/"); case "c++" - comment_specif = {"//", "\n"}; + [comment_start, comment_end] = deal ("//", "eol_char"); case "shell" - comment_specif = {"#", "\n"}; + [comment_start, comment_end] = deal ("#" , "eol_char"); case "matlab" - comment_specif = {"%", "\n"}; + [comment_start, comment_end] = deal ("%" , "eol_char"); otherwise - warning ("strread: unknown comment style '%s'", val); + if (ischar (varargin{n+1}) || + (numel (varargin{n+1}) == 1 && iscellstr (varargin{n+1}))) + [comment_start, comment_end] = deal (char (varargin{n+1}), "eol_char"); + elseif (iscellstr (varargin{n+1}) && numel (varargin{n+1}) == 2) + [comment_start, comment_end] = deal (varargin{n+1}{:}); + else + ## FIXME - a user may have numeric values specified: {'//', 7} + ## this will lead to an error in the warning message + error ("strread: unknown or unrecognized comment style '%s'", + varargin{n+1}); + endif endswitch case "delimiter" - delimiter_str = varargin {n+1}; + delimiter_str = varargin{n+1}; case "emptyvalue" - numeric_fill_value = varargin {n+1}; - case "bufsize" - ## XXX: We could synthesize this, but that just seems weird... - warning ("strread: property \"bufsize\" is not implemented"); + numeric_fill_value = varargin{n+1}; + case "expchars" + warning ('strread: property "expchars" is not implemented'); case "whitespace" - white_spaces = varargin {n+1}; - case "expchars" - warning ("strread: property \"expchars\" is not implemented"); + white_spaces = varargin{n+1}; + ## The following parameters are specific to textscan and textread + case "endofline" + eol_char = varargin{n+1}; + case "returnonerror" + err_action = varargin{n+1}; + case "multipledelimsasone" + mult_dlms_s1 = varargin{n+1}; + case "treatasempty" + if (iscellstr (varargin{n+1})) + empty_str = varargin{n+1}; + elseif (ischar (varargin{n+1})) + empty_str = varargin(n+1); + else + error ('strread: "treatasempty" value must be string or cellstr'); + endif otherwise - warning ("strread: unknown property \"%s\"", varargin {n}); + warning ('strread: unknown property "%s"', varargin{n}); endswitch endfor - if (isempty (delimiter_str)) - delimiter_str = white_spaces; + + ## First parse of FORMAT + if (strcmpi (strtrim (format), "%f")) + ## Default format specified. Expand it (to desired nargout) + fmt_words = cell (nargout, 1); + fmt_words (1:nargout) = format; + else + ## Determine the number of words per line as a first guess. Forms + ## like %f<literal>) (w/o delimiter in between) are fixed further on + format = strrep (format, "%", " %"); + fmt_words = regexp (format, '[^ ]+', 'match'); + ## Format conversion specifiers following literals w/o space/delim + ## in between are separate now. Separate those w trailing literals + idy2 = find (! cellfun ("isempty", strfind (fmt_words, "%"))); + a = strfind (fmt_words(idy2), "%"); + b = regexp (fmt_words(idy2), '[nfdus]', 'end'); + for jj = 1:numel (a) + ii = numel (a) - jj + 1; + if (! (length (fmt_words{idy2(ii)}) == b{ii}(1))) + ## Fix format_words + fmt_words(idy2(ii)+1 : end+1) = fmt_words(idy2(ii) : end); + fmt_words{idy2(ii)} = fmt_words{idy2(ii)}(a{ii} : b{ii}(1)); + fmt_words{idy2(ii)+1} = fmt_words{idy2(ii)+1}(b{ii}+1:end); + endif + endfor + endif + num_words_per_line = numel (fmt_words); + + ## Special handling for CRLF EOL character in str + if (! isempty (eol_char) && strcmp (eol_char, "\r\n")) + ## Strip CR from CRLF sequences + str = strrep (str, "\r\n", "\n"); + ## CR serves no further purpose in function + eol_char = "\n"; endif - ## Parse format string - idx = strfind (format, "%")'; - specif = format ([idx, idx+1]); - nspecif = length (idx); - idx_star = strfind (format, "%*"); - nfields = length (idx) - length (idx_star); - - if (max (nargout, 1) != nfields) - error ("strread: the number of output variables must match that specified byFORMAT"); - endif - - ## Remove comments + ## Remove comments in str if (comment_flag) - cstart = strfind (str, comment_specif{1}); - cstop = strfind (str, comment_specif{2}); - if (length (cstart) > 0) + ## Expand 'eol_char' here, after option processing which may have set value + comment_end = regexprep (comment_end, 'eol_char', eol_char); + cstart = strfind (str, comment_start); + cstop = strfind (str, comment_end); + ## Treat end of string as additional comment stop + if (isempty (cstop) || cstop(end) != length (str)) + cstop(end+1) = length (str); + endif + if (! isempty (cstart)) ## Ignore nested openers. [idx, cidx] = unique (lookup (cstop, cstart), "first"); if (idx(end) == length (cstop)) @@ -172,7 +305,7 @@ endif cstart = cstart(cidx); endif - if (length (cstop) > 0) + if (! isempty (cstop)) ## Ignore nested closers. [idx, cidx] = unique (lookup (cstart, cstop), "first"); if (idx(1) == 0) @@ -181,101 +314,406 @@ cstop = cstop(cidx); endif len = length (str); - c2len = length (comment_specif{2}); + c2len = length (comment_end); str = cellslices (str, [1, cstop + c2len], [cstart - 1, len]); str = [str{:}]; endif - ## Determine the number of words per line - format = strrep (format, "%", " %"); - [~, ~, ~, fmt_words] = regexp (format, '[^ ]+'); + if (! isempty (white_spaces)) + ## Remove any delimiter chars from white_spaces list + white_spaces = setdiff (white_spaces, delimiter_str); + endif + if (isempty (delimiter_str)) + delimiter_str = " "; + endif + if (! isempty (eol_char)) + ## Add eol_char to delimiter collection + delimiter_str = unique ([delimiter_str eol_char]); + ## .. and remove it from whitespace collection + white_spaces = strrep (white_spaces, eol_char, ''); + endif - num_words_per_line = numel (fmt_words); - for m = 1:numel(fmt_words) - ## Convert formats such as "%Ns" to "%s" (see the FIXME below) - if (length (fmt_words{m}) > 2) - if (strcmp (fmt_words{m}(1:2), "%*")) - fmt_words{m} = "%*"; - elseif (fmt_words{m}(1) == "%") - fmt_words{m} = fmt_words{m}([1, end]); - endif + pad_out = 0; + ## Trim whitespace if needed + ## FIXME: This is very complicated. Can this be simplified with regexprep? + if (! isempty (white_spaces)) + ## Check if trailing "\n" might signal padding output arrays to equal size + ## before it is trimmed away below + if ((str(end) == 10) && (nargout > 1)) + pad_out = 1; endif - endfor + ## Remove repeated white_space chars. First find white_space positions + idx = strchr (str, white_spaces); + ## Find repeated white_spaces + idx2 = ! (idx(2:end) - idx(1:end-1) - 1); + ## Set all whitespace chars to spaces + ## FIXME: this implies real spaces are always part of white_spaces + str(idx) = ' '; + ## Set all repeated white_space to \0 + str(idx(idx2)) = "\0"; + str = strsplit (str, "\0"); + ## Reconstruct trimmed str + str = cell2mat (str); + ## Remove leading & trailing space, but preserve delimiters. + str = strtrim (str); + ## FIXME: Double strrep on str is enormously expensive of CPU time. + ## Can this be eliminated + ## Wipe leading and trailing whitespace on each line (it may be delimiter too) + if (! isempty (eol_char)) + str = strrep (str, [eol_char " "], eol_char); + str = strrep (str, [" " eol_char], eol_char); + endif + endif ## Split 'str' into words - words = split_by (str, delimiter_str); + words = split_by (str, delimiter_str, mult_dlms_s1, eol_char); + if (! isempty (white_spaces)) + ## Trim leading and trailing white_spaces + ## FIXME: Is this correct? strtrim clears what matches isspace(), not + ## necessarily what is in white_spaces. + words = strtrim (words); + endif num_words = numel (words); + ## First guess at number of lines in file (ignoring leading/trailing literals) num_lines = ceil (num_words / num_words_per_line); - ## For each specifier + ## Replace TreatAsEmpty char sequences by empty strings + if (! isempty (empty_str)) + for ii = 1:numel (empty_str) + idz = strmatch (empty_str{ii}, words, "exact"); + words(idz) = {""}; + endfor + endif + + ## We now may have to cope with 3 cases: + ## A: Trailing literals (%f<literal>) w/o delimiter in between. + ## B: Leading literals (<literal>%f) w/o delimiter in between. + ## C. Skipping leftover parts of specified skip fields (%*N ) + ## fmt_words has been split properly now, but words{} has only been split on + ## delimiter positions. Some words columns may have to be split further. + ## We also don't know the number of lines (as EndOfLine may have been set to + ## "" (empty) by the caller). + + ## Find indices and pointers to possible literals in fmt_words + idf = cellfun ("isempty", strfind (fmt_words, "%")); + ## Find indices and pointers to conversion specifiers with fixed width + idg = ! cellfun ("isempty", regexp (fmt_words, '%\*?\d')); + idy = find (idf | idg); + + ## If needed, split up columns in three steps: + if (! isempty (idy)) + ## Try-catch because complexity of strings to read can be infinite + #try + + ## 1. Assess "period" in the split-up words array ( < num_words_per_line). + ## Could be done using EndOfLine but that prohibits EndOfLine = "" option. + ## Alternative below goes by simply parsing a first grab of words + ## and counting words until the fmt_words array is exhausted: + iwrd = 1; iwrdp = 0; iwrdl = length (words{iwrd}); + for ii = 1:numel (fmt_words) + + if (idf(ii)) + ## Literal expected + if (isempty (strfind (fmt_words{ii}, words(iwrd)))) + ## Not found in current word; supposed to be in next word + ++iwrd; iwrdp = 0; + if (ii < numel (fmt_words)) + iwrdl = length (words{iwrd}); + endif + else + ## Found it in current word. Subtract literal length + iwrdp += length (fmt_words{ii}); + if (iwrdp > iwrdl) + ## Parse error. Literal extends beyond delimiter (word boundary) + error ("strread: Literal '%s' (fmt spec # %d) does not match data", fmt_words{ii}, ii); + elseif (iwrdp == iwrdl) + ## Word completely "used up". Next word + ++iwrd; iwrdp = 0; + if (ii < numel (fmt_words)) + iwrdl = length (words{iwrd}); + endif + endif + endif + + elseif (idg(ii)) + ## Fixed width specifier (%N or %*N): read just a part of word + iwrdp += floor ... + (str2double (fmt_words{ii}(regexp(fmt_words{ii}, '\d') : end-1))); + if (iwrdp > iwrdl) + ## Error. Field extends beyond word boundary. + error ("strread: Field width '%s' (fmt spec # %d) extends beyond word limit", fmt_words{ii}, ii); + elseif (iwrdp == iwrdl) + ## Word completely "used up". Next word + ++iwrd; iwrdp = 0; iwrdl = length (words{iwrd}); + endif + + else + ## A simple format conv. specifier. Either (1) uses rest of word, or + ## (2) is squeezed between current iwrdp and next literal, or (3) uses + ## next word. (3) is already taken care of. So just check (1) & (2) + if (ii < numel (fmt_words) && idf(ii+1)) + ## Next fmt_word is a literal... + if (! index (words{iwrd}(iwrdp+1:end), fmt_words{ii+1})) + ## ...but not found in current word => field uses rest of word + ++iwrd; iwrdp = 0; iwrdl = length (words{iwrd}); + else + ## ..or it IS found. Add inferred width of current conversion field + iwrdp += index (words{iwrd}(iwrdp+1:end), fmt_words{ii+1}) - 1; + endif + elseif (iwrdp < iwrdl) + ## No bordering literal to the right => field occupies (rest of) word + ++iwrd; iwrdp = 0; + if (ii < numel (fmt_words)) + iwrdl = length (words{iwrd}); + endif + endif + + endif + endfor + ## Done + words_period = max (iwrd - 1, 1); + num_lines = ceil (num_words / words_period); + + ## 2. Pad words array so that it can be reshaped + tmp_lines = ceil (num_words / words_period); + num_words_padded = tmp_lines * words_period - num_words; + if (num_words_padded) + words = [words'; cell(num_words_padded, 1)]; + endif + words = reshape (words, words_period, tmp_lines); + + ## 3. Do the column splitting on rectangular words array + icol = 1; ii = 1; # icol = current column, ii = current fmt_word + while (ii <= num_words_per_line) + + ## Check if fmt_words(ii) contains a literal or fixed-width + if ((idf(ii) || idg(ii)) && (rows(words) < num_words_per_line)) + if (idf(ii)) + s = strfind (words(icol, 1), fmt_words{ii}); + if (isempty (s{:})) + error ("strread: Literal '%s' not found in column %d", fmt_words{ii}, icol); + endif + s = s{:}(1); + e = s(1) + length (fmt_words{ii}) - 1; + endif + if (! strcmp (fmt_words{ii}, words{icol, 1})) + ## Column doesn't exactly match literal => split needed. Insert a column + words(icol+1:end+1, :) = words(icol:end, :); + ## Watch out for empty cells + jptr = find (! cellfun ("isempty", words(icol, :))); + + ## Distinguish leading or trailing literals + if (! idg(ii) && ! isempty (s) && s(1) == 1) + ## Leading literal. Assign literal to icol, paste rest in icol + 1 + ## Apply only to those cells that do have something beyond literal + jptr = find (cellfun("length", words(icol+1, jptr), ... + "UniformOutput", false) > e(1)); + words(icol+1, :) = {""}; + words(icol+1, jptr) = cellfun ... + (@(x) substr(x, e(1)+1, length(x)-e(1)), words(icol, jptr), ... + "UniformOutput", false); + words(icol, jptr) = fmt_words{ii}; + + else + if (! idg(ii) && ! isempty (strfind (fmt_words{ii-1}, "%s"))) + ## Trailing literal. If preceding format == '%s' this is an error + warning ("Ambiguous '%s' specifier next to literal in column %d", icol); + elseif (idg(ii)) + ## Current field = fixed width. Strip into icol, rest in icol+1 + wdth = floor (str2double (fmt_words{ii}(regexp(fmt_words{ii}, ... + '\d') : end-1))); + words(icol+1, jptr) = cellfun (@(x) x(wdth+1:end), + words(icol,jptr), "UniformOutput", false); + words(icol, jptr) = strtrunc (words(icol, jptr), wdth); + else + ## FIXME: this assumes char(254)/char(255) won't occur in input! + clear wrds; + wrds(1:2:2*numel (words(icol, jptr))) = ... + strrep (words(icol, jptr), fmt_words{ii}, ... + [char(255) char(254)]); + wrds(2:2:2*numel (words(icol, jptr))-1) = char(255); + wrds = strsplit ([wrds{:}], char(255)); + words(icol, jptr) = ... + wrds(find (cellfun ("isempty", strfind (wrds, char(254))))); + wrds(find (cellfun ("isempty", strfind (wrds, char(254))))) ... + = char(255); + words(icol+1, jptr) = strsplit (strrep ([wrds{2:end}], ... + char(254), fmt_words{ii}), char(255)); + ## Former trailing literal may now be leading for next specifier + --ii; + endif + endif + endif + + else + ## Conv. specifier. Peek if next fmt_word needs split from current column + if (ii < num_words_per_line && idf(ii+1)) + if (! isempty (strfind (words{icol, 1}, fmt_words{ii+1}))) + --icol; + endif + endif + endif + ## Next fmt_word, next column + ++ii; ++icol; + endwhile + + ## Done. Reshape words back into 1 long vector and strip padded empty words + words = reshape (words, 1, numel (words))(1 : end-num_words_padded); + + #catch + # warning ("strread: unable to parse text or file with given format string"); + # return; + + #end_try_catch + endif + + ## For each specifier, process corresponding column k = 1; for m = 1:num_words_per_line - data = words (m:num_words_per_line:end); - ## Map to format - ## FIXME - add support for formats like "%4s" or "<%s>", "%[a-zA-Z]" - ## Someone with regexp experience is needed. - switch fmt_words{m} - case "%s" - data (end+1:num_lines) = {""}; - varargout {k} = data'; - k++; - case {"%d", "%f"} - n = cellfun (@isempty, data); - data = str2double (data); - data(n) = numeric_fill_value; - data (end+1:num_lines) = numeric_fill_value; - varargout {k} = data.'; - k++; - case {"%*", "%*s"} - ## skip the word - otherwise - ## Ensure descriptive content is consistent - if (numel (unique (data)) > 1 - || ! strcmpi (unique (data), fmt_words{m})) - error ("strread: FORMAT does not match data"); - endif - endswitch + try + if (format_repeat_count < 0) + data = words(m:num_words_per_line:end); + elseif (format_repeat_count == 0) + data = {}; + else + lastline = ... + min (num_words_per_line * format_repeat_count + m - 1, numel (words)); + data = words(m:num_words_per_line:lastline); + endif + + ## Map to format + ## FIXME - add support for formats like "<%s>", "%[a-zA-Z]" + ## Someone with regexp experience is needed. + switch fmt_words{m}(1:min (2, length (fmt_words{m}))) + case "%s" + if (pad_out) + data(end+1:num_lines) = {""}; + endif + varargout{k} = data'; + k++; + case {"%d", "%u", "%f", "%n"} + n = cellfun ("isempty", data); + ### FIXME - erroneously formatted data lead to NaN, not an error + data = str2double (data); + if (! isempty (regexp (fmt_words{m}, "%[du]"))) + ## Cast to integer + ## FIXME: NaNs will be transformed into zeros + data = int32 (data); + end + data(n) = numeric_fill_value; + if (pad_out) + data(end+1:num_lines) = numeric_fill_value; + endif + varargout{k} = data.'; + k++; + case {"%0", "%1", "%2", "%3", "%4", "%5", "%6", "%7", "%8", "%9"} + nfmt = strsplit (fmt_words{m}(2:end-1), '.'); + swidth = str2double (nfmt{1}); + switch fmt_words{m}(end) + case {"d", "u", "f", "n%"} + n = cellfun ("isempty", data); + ### FIXME - erroneously formatted data lead to NaN, not an error + ### => ReturnOnError can't be implemented for numeric data + data = str2double (strtrunc (data, swidth)); + data(n) = numeric_fill_value; + if (pad_out) + data(end+1:num_lines) = numeric_fill_value; + endif + if (numel (nfmt) > 1) + sprec = str2double (nfmt{2}); + data = 10^-sprec * round (10^sprec * data); + elseif (! isempty (regexp (fmt_words{m}, "[du]"))) + ## Cast to integer + ## FIXME: NaNs will be transformed into zeros + data = int32 (data); + end + varargout{k} = data.'; + k++; + case "s" + if (pad_out) + data(end+1:num_lines) = {""} + endif + varargout{k} = strtrunc (data, swidth)'; + k++; + otherwise + endswitch + case {"%*", "%*s"} + ## skip the word + otherwise + ## Ensure descriptive content is consistent. + ## Test made a bit lax to accomodate for incomplete last lines + n = find (! cellfun ("isempty", data)); + if (numel (unique (data(n))) > 1 + || ! strcmpi (unique (data), fmt_words{m})) + error ("strread: FORMAT does not match data"); + endif + endswitch + catch + ## As strread processes columnwise, ML-compatible error processing + ## (row after row) is not feasible. In addition Octave sets unrecognizable + ## numbers to NaN w/o error. But maybe Octave is better in this respect. + if (err_action) + ## Just try the next column where ML bails out + else + rethrow (lasterror); + endif + end_try_catch endfor + endfunction -function out = split_by (text, sep) - sep = union (sep, "\n"); - pat = sprintf ('[^%s]+', sep); - [~, ~, ~, out] = regexp (text, pat); - out(cellfun (@isempty, out)) = {""}; - out = strtrim (out); +function out = split_by (text, sep, mult_dlms_s1, eol_char) + + ## Check & if needed, process MultipleDelimsAsOne parameter + if (mult_dlms_s1) + mult_dlms_s1 = true; + ## FIXME: Should re-implement strsplit() function here in order + ## to avoid strrep on megabytes of data. + ## If \n is in sep collection we need to enclose it in spaces in text + ## to avoid it being included in consecutive delim series + text = strrep (text, eol_char, [" " eol_char " "]); + else + mult_dlms_s1 = false; + endif + + ## Split text string along delimiters + out = strsplit (text, sep, mult_dlms_s1); + ## In case of trailing delimiter, strip stray last empty word + if (!isempty (out) && any (sep == text(end))) + out(end) = []; + endif + + ## Empty cells converted to empty cellstrings. + out(cellfun ("isempty", out)) = {""}; + endfunction + %!test %! [a, b] = strread ("1 2", "%f%f"); -%! assert (a == 1 && b == 2); - -%!test -%! str = "# comment\n# comment\n1 2 3"; -%! [a, b] = strread (str, '%d %s', 'commentstyle', 'shell'); -%! assert (a, [1; 3]); -%! assert (b, {"2"; ""}); +%! assert (a, 1); +%! assert (b, 2); %!test %! str = ''; %! a = rand (10, 1); -%! b = char (round (65 + 20 * rand (10, 1))); +%! b = char (randi ([65, 85], 10, 1)); %! for k = 1:10 -%! str = sprintf ('%s %.6f %s\n', str, a (k), b (k)); +%! str = sprintf ('%s %.6f %s\n', str, a(k), b(k)); %! endfor %! [aa, bb] = strread (str, '%f %s'); -%! assert (a, aa, 1e-5); +%! assert (a, aa, 1e-6); %! assert (cellstr (b), bb); %!test %! str = ''; %! a = rand (10, 1); -%! b = char (round (65 + 20 * rand (10, 1))); +%! b = char (randi ([65, 85], 10, 1)); %! for k = 1:10 -%! str = sprintf ('%s %.6f %s\n', str, a (k), b (k)); +%! str = sprintf ('%s %.6f %s\n', str, a(k), b(k)); %! endfor %! aa = strread (str, '%f %*s'); -%! assert (a, aa, 1e-5); +%! assert (a, aa, 1e-6); %!test %! str = sprintf ('/* this is\nacomment*/ 1 2 3'); @@ -283,6 +721,12 @@ %! assert (a, [1; 2; 3]); %!test +%! str = "# comment\n# comment\n1 2 3"; +%! [a, b] = strread (str, '%n %s', 'commentstyle', 'shell', 'endofline', "\n"); +%! assert (a, [1; 3]); +%! assert (b, {"2"}); + +%!test %! str = sprintf ("Tom 100 miles/hr\nDick 90 miles/hr\nHarry 80 miles/hr"); %! fmt = "%s %f miles/hr"; %! c = cell (1, 2); @@ -294,3 +738,65 @@ %! a = strread ("a b c, d e, , f", "%s", "delimiter", ","); %! assert (a, {"a b c"; "d e"; ""; "f"}); +%!test +%! # Bug #33536 +%! [a, b, c] = strread ("1,,2", "%s%s%s", "delimiter", ","); +%! assert (a{1}, '1'); +%! assert (b{1}, ''); +%! assert (c{1}, '2'); + +%!test +%! # Bug #33536 +%! a = strread ("[SomeText]", "[%s", "delimiter", "]"); +%! assert (a{1}, "SomeText"); + +%!test +%! dat = "Data file.\r\n= = = = =\r\nCOMPANY : <Company name>\r\n"; +%! a = strread (dat, "%s", 'delimiter', "\n", 'whitespace', '', 'endofline', "\r\n"); +%! assert (a{2}, "= = = = ="); +%! assert (double (a{3}(end-5:end)), [32 110 97 109 101 62]); + +%!test +%! [a, b, c, d] = strread ("1,2,3,,5,6", "%d%f%d%f", 'delimiter', ','); +%! assert (c, int32 (3)); +%! assert (d, NaN); + +%!test +%! [a, b, c, d] = strread ("1,2,3,,5,6\n", "%d%d%f%d", 'delimiter', ','); +%! assert (c, [3; NaN]); +%! assert (d, int32 ([0; 0])); + +%!test +%! # Default format (= %f) +%1 [a, b, c] = strread ("0.12 0.234 0.3567"); +%1 assert (a, 0.12); +%1 assert (b, 0.234); +%1 assert (c, 0.3567); + +%!test +%! [a, b] = strread('0.41 8.24 3.57 6.24 9.27', "%f%f", 2, 'delimiter', ' '); +%1 assert (a, [0.41; 3.57]); + +%!test +%! # TreatAsEmpty +%! [a, b, c, d] = strread ("1,2,3,NN,5,6\n", "%d%d%d%f", 'delimiter', ',', 'TreatAsEmpty', 'NN'); +%! assert (c, int32 ([3; 0])); +%! assert (d, [NaN; NaN]); + +%!test +%! # No delimiters at all besides EOL. Plain reading numbers & strings +%! str = "Text1Text2Text\nText398Text4Text\nText57Text"; +%! c = textscan (str, "Text%dText%1sText"); +%! assert (c{1}, int32 ([1; 398; 57])); +%! assert (c{2}(1:2), {'2'; '4'}); +%! assert (isempty (c{2}{3}), true); + +%% MultipleDelimsAsOne +%!test +%! str = "11, 12, 13,, 15\n21,, 23, 24, 25\n,, 33, 34, 35"; +%! [a b c d] = strread (str, "%f %f %f %f", 'delimiter', ',', 'multipledelimsasone', 1, 'endofline', "\n"); +%! assert (a', [11, 21, NaN]); +%! assert (b', [12, 23, 33]); +%! assert (c', [13, 24, 34]); +%! assert (d', [15, 25, 35]); +
--- a/scripts/io/textread.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/io/textread.m Fri Aug 12 14:16:34 2011 -0400 @@ -19,30 +19,43 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {[@var{a}, @dots{}] =} textread (@var{filename}) ## @deftypefnx {Function File} {[@var{a}, @dots{}] =} textread (@var{filename}, @var{format}) +## @deftypefnx {Function File} {[@var{a}, @dots{}] =} textread (@var{filename}, @var{format}, @var{n}) ## @deftypefnx {Function File} {[@var{a}, @dots{}] =} textread (@var{filename}, @var{format}, @var{prop1}, @var{value1}, @dots{}) +## @deftypefnx {Function File} {[@var{a}, @dots{}] =} textread (@var{filename}, @var{format}, @var{n}, @var{prop1}, @var{value1}, @dots{}) ## Read data from a text file. ## ## The file @var{filename} is read and parsed according to @var{format}. The ## function behaves like @code{strread} except it works by parsing a file -## instead -## of a string. See the documentation of @code{strread} for details. +## instead of a string. See the documentation of @code{strread} for details. +## ## In addition to the options supported by @code{strread}, this function -## supports one more: +## supports two more: +## ## @itemize ## @item "headerlines": +## The first @var{value} number of lines of @var{filename} are skipped. +## +## @item "endofline": +## Specify a single character or "\r\n". If no value is given, it will be +## inferred from the file. If set to "" (empty string) EOLs are ignored as +## delimiters. ## @end itemize -## The first @var{value} number of lines of @var{str} are skipped. -## @seealso{strread, load, dlmread, fscanf} +## +## The optional input @var{n} specifes the number of times to use +## @var{format} when parsing, i.e., the format repeat count. +## +## @seealso{strread, load, dlmread, fscanf, textscan} ## @end deftypefn function varargout = textread (filename, format = "%f", varargin) + ## Check input if (nargin < 1) print_usage (); endif - if (!ischar (filename) || !ischar (format)) - error ("textread: first and second input arguments must be strings"); + if (! ischar (filename) || ! ischar (format)) + error ("textread: FILENAME and FORMAT arguments must be strings"); endif ## Read file @@ -51,21 +64,85 @@ error ("textread: could not open '%s' for reading", filename); endif - ## Maybe skip header lines + ## Skip header lines if requested headerlines = find (strcmpi (varargin, "headerlines"), 1); - if (! isempty (headerlines)) - hdr_lines = floor (varargin{headerlines + 1}); - ## Beware of zero valued headerline, fskipl will count lines to EOF then - if (hdr_lines > 0) - fskipl (fid, hdr_lines); - endif + ## Beware of zero valued headerline, fskipl would skip to EOF + if (! isempty (headerlines) && (varargin{headerlines + 1} > 0)) + fskipl (fid, varargin{headerlines + 1}); varargin(headerlines:headerlines+1) = []; endif - str = fread (fid, "char=>char").'; + if (nargin > 2 && isnumeric (varargin{1})) + nlines = varargin{1}; + else + nlines = Inf; + endif + + if (isfinite (nlines) && (nlines >= 0)) + str = tmp_str = ""; + n = 0; + ## FIXME: Can this be done without slow loop? + while (ischar (tmp_str) && n++ <= nlines) + str = strcat (str, tmp_str); + tmp_str = fgets (fid); + endwhile + else + str = fread (fid, "char=>char").'; + endif fclose (fid); + if (isempty (str)) + warning ("textread: empty file"); + return; + endif + + endofline = find (strcmpi (varargin, "endofline"), 1); + if (! isempty (endofline)) + ## 'endofline' option set by user. + if (! ischar (varargin{endofline + 1})); + error ("textread: character value required for EndOfLine"); + endif + else + ## Determine EOL from file. Search for EOL candidates in first 3000 chars + eol_srch_len = min (length (str), 3000); + ## First try DOS (CRLF) + if (! isempty (findstr ("\r\n", str(1 : eol_srch_len)))) + eol_char = "\r\n"; + ## Perhaps old Macintosh? (CR) + elseif (! isempty (findstr ("\r", str(1 : eol_srch_len)))) + eol_char = "\r"; + ## Otherwise, use plain UNIX (LF) + else + eol_char = "\n"; + endif + ## Set up default endofline param value + varargin(end+1:end+2) = {'endofline', eol_char}; + endif + + ## Set up default whitespace param value if needed + if (isempty (find (strcmpi ('whitespace', varargin)))) + varargin(end+1:end+2) = {'whitespace', " \b\t"}; + endif + ## Call strread to make it do the real work [varargout{1:max (nargout, 1)}] = strread (str, format, varargin {:}); endfunction + + +%!test +%! f = tmpnam(); +%! d = rand (5, 3); +%! dlmwrite (f, d, 'precision', '%5.2f'); +%! [a, b, c] = textread (f, "%f %f %f", "delimiter", ",", "headerlines", 3); +%! unlink(f); +%! assert (a, d(4:5, 1), 1e-2); +%! assert (b, d(4:5, 2), 1e-2); +%! assert (c, d(4:5, 3), 1e-2); + +%% Test input validation +%!error textread () +%!error textread (1) +%!error <arguments must be strings> textread (1, '%f') +%!error <arguments must be strings> textread ("fname", 1) +
--- a/scripts/io/textscan.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/io/textscan.m Fri Aug 12 14:16:34 2011 -0400 @@ -22,23 +22,40 @@ ## @deftypefnx {Function File} {@var{C} =} textscan (@var{fid}, @var{format}, @var{param}, @var{value}, @dots{}) ## @deftypefnx {Function File} {@var{C} =} textscan (@var{fid}, @var{format}, @var{n}, @var{param}, @var{value}, @dots{}) ## @deftypefnx {Function File} {@var{C} =} textscan (@var{str}, @dots{}) -## @deftypefnx {Function File} {[@var{C}, @var{position}] =} textscan (@dots{}) -## Read data from a text file. +## @deftypefnx {Function File} {[@var{C}, @var{position}] =} textscan (@var{fid}, @dots{}) +## Read data from a text file or string. ## ## The file associated with @var{fid} is read and parsed according to ## @var{format}. The function behaves like @code{strread} except it works by ## parsing a file instead of a string. See the documentation of -## @code{strread} for details. In addition to the options supported by -## @code{strread}, this function supports one more: +## @code{strread} for details. +## +## In addition to the options supported by +## @code{strread}, this function supports a few more: +## ## @itemize +## @item "collectoutput": +## A value of 1 or true instructs textscan to concatenate consecutive columns +## of the same class in the output cell array. A value of 0 or false (default) +## leaves output in distinct columns. +## +## @item "endofline": +## Specify "\r", "\n" or "\r\n" (for CR, LF, or CRLF). If no value is given, +## it will be inferred from the file. If set to "" (empty string) EOLs are +## ignored as delimiters and added to whitespace. +## ## @item "headerlines": +## The first @var{value} number of lines of @var{fid} are skipped. +## +## @item "returnonerror": +## If set to numerical 1 or true (default), return normally when read errors +## have been encountered. If set to 0 or false, return an error and no data. ## @end itemize -## The first @var{value} number of lines of @var{str} are skipped. ## -## The optional input, @var{n}, specifes the number of lines to be read from -## the file, associated with @var{fid}. +## The optional input @var{n} specifes the number of times to use +## @var{format} when parsing, i.e., the format repeat count. ## -## The output, @var{C}, is a cell array whose length is given by the number +## The output @var{C} is a cell array whose length is given by the number ## of format specifiers. ## ## The second output, @var{position}, provides the position, in characters, @@ -47,89 +64,208 @@ ## @seealso{dlmread, fscanf, load, strread, textread} ## @end deftypefn -function [C, p] = textscan (fid, format, varargin) +function [C, position] = textscan (fid, format = "%f", varargin) ## Check input if (nargin < 1) print_usage (); - elseif (nargin == 1 || isempty (format)) + endif + + if (isempty (format)) format = "%f"; endif - if (nargin > 2 && isnumeric (varargin{1})) - nlines = varargin{1}; - args = varargin(2:end); + if (! (isa (fid, "double") && fid > 0) && ! ischar (fid)) + error ("textscan: first argument must be a file id or character string"); + endif + + if (! ischar (format)) + error ("textscan: FORMAT must be a string"); + endif + + args = varargin; + if (nargin > 2 && isnumeric (args{1})) + nlines = args{1}; else nlines = Inf; - args = varargin; endif if (! any (strcmpi (args, "emptyvalue"))) ## Matlab returns NaNs for missing values - args{end+1} = "emptyvalue"; - args{end+1} = NaN; + args(end+1:end+2) = {'emptyvalue', NaN}; + endif + + ## Check default parameter values that differ for strread & textread + + ipos = find (strcmpi (args, "whitespace")); + if (isempty (ipos)) + ## Matlab default whitespace = " \b\t" + args(end+1:end+2) = {'whitespace', " \b\t"}; + whitespace = " \b\t"; + else + ## Check if there's at least one string format specifier + fmt = strrep (format, "%", " %"); + fmt = regexp (fmt, '[^ ]+', 'match'); + fmt = strtrim (fmt(strmatch ("%", fmt))) + has_str_fmt = all (cellfun ("isempty", strfind (strtrim (fmt(strmatch ("%", fmt))), 's'))); + ## If there is a format, AND whitespace value = empty, + ## don't add a space (char(32)) to whitespace + if (! (isempty (args{ipos+1}) && has_str_fmt)) + args{ipos+1} = unique ([" ", whitespace]); + endif + endif + + if (! any (strcmpi (args, "delimiter"))) + ## Matlab says default delimiter = whitespace. + ## strread() will pick this up further + args(end+1:end+2) = {'delimiter', ""}; + endif + + collop = false; + ipos = find (strcmpi (args, "collectoutput")); + if (! isempty (ipos)) + ## Search & concatenate consecutive columns of same class requested + if (isscalar (args{ipos+1}) + && (islogical (args{ipos+1}) || isnumeric (args{ipos+1}))) + collop = args{ipos+1}; + else + warning ("textscan: illegal value for CollectOutput parameter - ignored"); + endif + ## Remove argument before call to strread() below + args(ipos:ipos+1) = []; + endif + + if (any (strcmpi (args, "returnonerror"))) + ## Because of the way strread() reads data (columnwise) this parameter + ## can't be neatly implemented. strread() will pick it up anyway + warning ('textscan: ReturnOnError is not fully implemented'); + else + ## Set default value (=true) + args(end+1:end+2) = {"returnonerror", 1}; + endif + + if (ischar (fid)) + ## Read from a text string + if (nargout == 2) + error ("textscan: cannot provide position information for character input"); + endif + str = fid; + else + ## Skip header lines if requested + headerlines = find (strcmpi (args, "headerlines"), 1); + ## Beware of zero valued headerline, fskipl would skip to EOF + if (! isempty (headerlines) && (args{headerlines + 1} > 0)) + fskipl (fid, varargin{headerlines + 1}); + args(headerlines:headerlines+1) = []; + endif + if (isfinite (nlines) && (nlines >= 0)) + str = tmp_str = ""; + n = 0; + ## FIXME: Can this be done without slow loop? + while (ischar (tmp_str) && n++ < nlines) + tmp_str = fgets (fid); + if (ischar (tmp_str)) + str = strcat (str, tmp_str); + endif + endwhile + else + str = fread (fid, "char=>char").'; + endif endif - if (isa (fid, "double") && fid > 0 || ischar (fid)) - if (ischar (format)) - if (ischar (fid)) - if (nargout == 2) - error ("textscan: cannot provide position information for character input"); - endif - str = fid; - else - ## Maybe skip header lines - headerlines = find (strcmpi (args, "headerlines"), 1); - if (! isempty (headerlines)) - hdr_lines = floor (varargin{headerlines + 1}); - ## Beware of zero valued headerline, fskipl will count lines to EOF - if (hdr_lines > 0) - fskipl (fid, hdr_lines); - endif - endif - if (isfinite (nlines)) - str = ""; - for n = 1:nlines - str = strcat (str, fgets (fid)); - endfor - else - str = fread (fid, "char=>char").'; - endif + ## Check for empty result + if (isempty (str)) + warning ("textscan: no data read"); + C = []; + return; + endif + + ## Check value of 'endofline'. String or file doesn't seem to matter + endofline = find (strcmpi (args, "endofline"), 1); + if (! isempty (endofline)) + if (ischar (args{endofline + 1})) + eol_char = args{endofline + 1}; + if (isempty (strmatch (eol_char, {"", "\n", "\r", "\r\n"}, 'exact'))) + error ("textscan: illegal EndOfLine character value specified"); endif - - ## Determine the number of data fields - num_fields = numel (strfind (format, "%")) - ... - numel (idx_star = strfind (format, "%*")); - - ## Call strread to make it do the real work - C = cell (1, num_fields); - [C{:}] = strread (str, format, args{:}); - - if (ischar (fid) && isfinite (nlines)) - C = cellfun (@(x) x(1:nlines), C, "uniformoutput", false); - endif - - if (nargout == 2) - p = ftell (fid); - endif - else - error ("textscan: FORMAT must be a valid specification"); + error ("textscan: character value required for EndOfLine"); endif else - error ("textscan: first argument must be a file id or character string"); + ## Determine EOL from file. Search for EOL candidates in first 3000 chars + eol_srch_len = min (length (str), 3000); + ## First try DOS (CRLF) + if (! isempty (findstr ("\r\n", str(1 : eol_srch_len)))) + eol_char = "\r\n"; + ## Perhaps old Macintosh? (CR) + elseif (! isempty (findstr ("\r", str(1 : eol_srch_len)))) + eol_char = "\r"; + ## Otherwise, use plain UNIX (LF) + else + eol_char = "\n"; + endif + ## Set up the default endofline param value + args(end+1:end+2) = {'endofline', eol_char}; + endif + + ## Determine the number of data fields + num_fields = numel (strfind (format, "%")) - numel (strfind (format, "%*")); + + ## Strip trailing EOL to avoid returning stray missing values (f. strread) + if (strcmp (str(end-length (eol_char) + 1 : end), eol_char)); + str(end-length (eol_char) + 1 : end) = ""; + endif + + ## Call strread to make it do the real work + C = cell (1, num_fields); + [C{:}] = strread (str, format, args{:}); + + ## If requested, collect output columns of same class + if (collop) + C = colloutp (C); endif + if (nargout == 2) + position = ftell (fid); + endif + +endfunction + + +## Collect consecutive columns of same class into one cell column +function C = colloutp (C) + + ## Start at rightmost column and work backwards to avoid ptr mixup + ii = numel (C); + while ii > 1 + clss1 = class (C{ii}); + jj = ii; + while (jj > 1 && strcmp (clss1, class (C{jj - 1}))) + ## Column to the left is still same class; check next column to the left + --jj; + endwhile + if (jj < ii) + ## Concatenate columns into current column + C{jj} = [C{jj : ii}]; + ## Wipe concatenated columns to the right, resume search to the left + C(jj+1 : ii) = []; + ii = jj - 1; + else + ## No similar class in column to the left, search from there + --ii; + endif + endwhile + endfunction %!test %! str = "1, 2, 3, 4\n 5, , , 8\n 9, 10, 11, 12"; %! fmtstr = "%f %d %f %s"; %! c = textscan (str, fmtstr, 2, "delimiter", ",", "emptyvalue", -Inf); -%! assert (isequal (c{1}, [1;5])) +%! assert (isequal (c{1}, [1;5])); %! assert (length (c{1}), 2); -%! assert (iscellstr (c{4})) -%! assert (isequal (c{3}, [3; -Inf])) +%! assert (iscellstr (c{4})); +%! assert (isequal (c{3}, [3; -Inf])); %!test %! b = [10:10:100]; @@ -137,7 +273,60 @@ %! str = sprintf ("%g miles/hr = %g kilometers/hr\n", b); %! fmt = "%f miles/hr = %f kilometers/hr"; %! c = textscan (str, fmt); -%! assert (b(1,:)', c{1}) -%! assert (b(2,:)', c{2}) +%! assert (b(1,:)', c{1}, 1e-5); +%! assert (b(2,:)', c{2}, 1e-5); + +#%!test +#%! str = "13, 72, NA, str1, 25\r\n// Middle line\r\n36, na, 05, str3, 6"; +#%! a = textscan(str, '%d %n %f %s %n', 'delimiter', ',','treatAsEmpty', {'NA', 'na'},'commentStyle', '//'); +#%! assert (a{1}, int32([13; 36])); +#%! assert (a{2}, [72; NaN]); +#%! assert (a{3}, [NaN; 5]); +#%! assert (a{4}, {"str1"; "str3"}); +#%! assert (a{5}, [25; 6]); + +%!test +%! str = "Km:10 = hhhBjjj miles16hour\r\n"; +%! str = [str "Km:15 = hhhJjjj miles241hour\r\n"]; +%! str = [str "Km:2 = hhhRjjj miles3hour\r\n"]; +%! str = [str "Km:25 = hhhZ\r\n"]; +%! fmt = "Km:%d = hhh%1sjjj miles%dhour"; +%! a = textscan (str, fmt, 'delimiter', ' '); +%! assert (a{1}', int32([10 15 2 25])); +%! assert (a{2}', {'B' 'J' 'R' 'Z'}); +%! assert (a{3}', int32([16 241 3 0])); + +%% Test with default endofline parameter +%!test +%! c = textscan ("L1\nL2", "%s"); +%! assert (c{:}, {"L1"; "L2"}); +%% Test with endofline parameter set to '' (empty) - newline should be in word +%!test +%! c = textscan ("L1\nL2", "%s", 'endofline', ''); +%! assert (int8(c{:}{:}), int8([ 76, 49, 10, 76, 50 ])); +%!test +%! # No delimiters at all besides EOL. Skip fields, even empty fields +%! str = "Text1Text2Text\nTextText4Text\nText57Text"; +%! c = textscan (str, "Text%*dText%dText"); +%! assert (c{1}, int32 ([2; 4; 0])); + +%!test +%% CollectOutput test +%! b = [10:10:100]; +%! b = [b; 8*b/5; 8*b*1000/5]; +%! str = sprintf ("%g miles/hr = %g (%g) kilometers (meters)/hr\n", b); +%! fmt = "%f miles%s %s %f (%f) kilometers %*s"; +%! c = textscan (str, fmt, 'collectoutput', 1); +%! assert (size(c{3}), [10, 2]); +%! assert (size(c{2}), [10, 2]); + +%% Test input validation +%!error textscan () +%!error textscan (single (4)) +%!error textscan ({4}) +%!error <must be a string> textscan ("Hello World", 2) +%!error <cannot provide position information> [C, pos] = textscan ("Hello World") +%!error <character value required> textscan ("Hello World", '%s', 'EndOfLine', 3) +
--- a/scripts/linear-algebra/commutation_matrix.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/linear-algebra/commutation_matrix.m Fri Aug 12 14:16:34 2011 -0400 @@ -95,3 +95,25 @@ endfor endfunction + +%!test +%! c = commutation_matrix(1,1); +%! assert(c,1); + +%!test +%! A = rand(3,5); +%! vc = vec(A); +%! vr = vec(A'); +%! c = commutation_matrix(3,5); +%! assert(c*vc,vr); + +%!test +%! A = rand(4,6); +%! vc = vec(A); +%! vr = vec(A'); +%! c = commutation_matrix(4,6); +%! assert(c*vc,vr); + +%!error commutation_matrix(0,0); +%!error commutation_matrix(1,0); +%!error commutation_matrix(0,1);
--- a/scripts/linear-algebra/gmres.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,214 +0,0 @@ -## Copyright (C) 2009-2011 Carlo de Falco -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by the -## Free Software Foundation; either version 3 of the License, or (at your -## option) any later version. -## -## Octave is distributed in the hope that it will be useful, but WITHOUT -## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -## for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {@var{x} =} gmres (@var{A}, @var{b}, @var{m}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0}) -## @deftypefnx {Function File} {@var{x} =} gmres (@var{A}, @var{b}, @var{m}, @var{rtol}, @var{maxit}, @var{P}) -## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} gmres (@dots{}) -## Solve @code{A x = b} using the Preconditioned GMRES iterative method -## with restart, a.k.a. PGMRES(m). -## -## @itemize @minus -## @item @var{rtol} is the relative tolerance, -## if not given or set to [] the default value 1e-6 is used. -## -## @item @var{maxit} is the maximum number of outer iterations, -## if not given or set to [] the default value -## @code{min (10, numel (b) / restart)} is used. -## -## @item @var{x0} is the initial guess, -## if not given or set to [] the default value @code{zeros(size (b))} is used. -## -## @item @var{m} is the restart parameter, -## if not given or set to [] the default value @code{numel (b)} is used. -## @end itemize -## -## Argument @var{A} can be passed as a matrix, function handle, or -## inline function @code{f} such that @code{f(x) = A*x}. -## -## The preconditioner @var{P} is given as @code{P = M1 * M2}. -## Both @var{M1} and @var{M2} can be passed as a matrix, function handle, or -## inline function @code{g} such that @code{g(x) = M1\x} or @code{g(x) = M2\x}. -## -## Besides the vector @var{x}, additional outputs are: -## -## @itemize @minus -## @item @var{flag} indicates the exit status: -## -## @table @asis -## @item 0 : iteration converged to within the specified tolerance -## -## @item 1 : maximum number of iterations exceeded -## -## @item 2 : unused, but skipped for compatibility -## -## @item 3 : algorithm reached stagnation -## @end table -## -## @item @var{relres} is the final value of the relative residual. -## -## @item @var{iter} is a vector containing the number of outer iterations and -## total iterations performed. -## -## @item @var{resvec} is a vector containing the relative residual at each -## iteration. -## @end itemize -## -## @seealso{pcg, cgs, bicgstab} -## @end deftypefn - -function [x, flag, prec_res_norm, itcnt] = gmres (A, b, restart, rtol, maxit, M1, M2, x0) - - if (nargin < 2 || nargin > 8) - print_usage (); - end - - if (ischar (A)) - Ax = str2func (A); - elseif (ismatrix (A)) - Ax = @(x) A*x; - elseif (isa (A, "function_handle")) - Ax = A; - else - error ("gmres: A must be a function or matrix"); - endif - - if (nargin < 3 || isempty (restart)) - restart = rows (b); - endif - - if (nargin < 4 || isempty (rtol)) - rtol = 1e-6; - endif - - if (nargin < 5 || isempty (maxit)) - maxit = min (rows (b)/restart, 10); - endif - - if (nargin < 6 || isempty (M1)) - M1m1x = @(x) x; - elseif (ischar (M1)) - M1m1x = str2func (M1); - elseif (ismatrix (M1)) - M1m1x = @(x) M1 \ x; - elseif (isa (M1, "function_handle")) - M1m1x = M1; - else - error ("gmres: preconditioner M1 must be a function or matrix"); - endif - - if (nargin < 7 || isempty (M2)) - M2m1x = @(x) x; - elseif (ischar (M2)) - M2m1x = str2func (M2); - elseif (ismatrix (M2)) - M2m1x = @(x) M2 \ x; - elseif (isa (M2, "function_handle")) - M2m1x = M2; - else - error ("gmres: preconditioner M2 must be a function or matrix"); - endif - - Pm1x = @(x) M2m1x (M1m1x (x)); - - if (nargin < 8 || isempty (x0)) - x0 = zeros (size (b)); - endif - - x_old = x0; - x = x_old; - prec_res = Pm1x (b - Ax (x_old)); - prec_res_norm = norm (prec_res, 2); - - B = zeros (restart + 1, 1); - V = zeros (rows (x), restart); - H = zeros (restart + 1, restart); - - ## begin loop - iter = 1; - restart_it = restart + 1; - resids = zeros (maxit, 1); - resids(1) = prec_res_norm; - prec_b_norm = norm (Pm1x (b), 2); - flag = 1; - - while ((iter <= maxit * restart) && (prec_res_norm > rtol * prec_b_norm)) - - ## restart - if (restart_it > restart) - restart_it = 1; - x_old = x; - prec_res = Pm1x (b - Ax (x_old)); - prec_res_norm = norm (prec_res, 2); - B(1) = prec_res_norm; - H(:) = 0; - V(:, 1) = prec_res / prec_res_norm; - endif - - ## basic iteration - tmp = Pm1x (Ax (V(:, restart_it))); - [V(:,restart_it+1), H(1:restart_it+1, restart_it)] = mgorth (tmp, V(:,1:restart_it)); - - Y = (H(1:restart_it+1, 1:restart_it) \ B (1:restart_it+1)); - - little_res = B(1:restart_it+1) - H(1:restart_it+1, 1:restart_it) * Y(1:restart_it); - prec_res_norm = norm (little_res, 2); - - x = x_old + V(:, 1:restart_it) * Y(1:restart_it); - - resids(iter) = prec_res_norm ; - if (norm (x - x_old, inf) <= eps) - flag = 3; - break - endif - - restart_it++ ; iter++; - endwhile - - if (prec_res_norm > rtol * prec_b_norm) - flag = 0; - endif - - resids = resids(1:iter-1); - itcnt = [floor(maxit/restart), rem(maxit, restart)]; -endfunction - - -%!shared A, b, dim -%! dim = 100; -%!test -%! A = spdiags ([-ones(dim,1) 2*ones(dim,1) ones(dim,1)], [-1:1], dim, dim); -%! b = ones(dim, 1); -%! x = gmres (A, b, 10, 1e-10, dim, @(x) x./diag(A), [], b); -%! assert(x, A\b, 1e-9*norm(x,inf)); -%! -%!test -%! x = gmres (A, b, dim, 1e-10, 1e4, @(x) diag(diag(A))\x, [], b); -%! assert(x, A\b, 1e-7*norm(x,inf)); -%! -%!test -%! A = spdiags ([[1./(2:2:2*(dim-1)) 0]; 1./(1:2:2*dim-1); [0 1./(2:2:2*(dim-1))]]', -1:1, dim, dim); -%! A = A'*A; -%! b = rand (dim, 1); -%! [x, resids] = gmres (@(x) A*x, b, dim, 1e-10, dim, @(x) x./diag(A), [], []); -%! assert(x, A\b, 1e-9*norm(x,inf)) -%! x = gmres (@(x) A*x, b, dim, 1e-10, 1e6, @(x) diag(diag(A))\x, [], []); -%! assert(x, A\b, 1e-9*norm(x,inf)); -%!test -%! x = gmres (@(x) A*x, b, dim, 1e-10, 1e6, @(x) x./diag(A), [], []); -%! assert(x, A\b, 1e-7*norm(x,inf));
--- a/scripts/linear-algebra/isdefinite.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/linear-algebra/isdefinite.m Fri Aug 12 14:16:34 2011 -0400 @@ -63,3 +63,22 @@ endif endfunction + +%!test +%! A = [-1 0; 0 -1]; +%! assert (isdefinite (A), -1) + +%!test +%! A = [1 0; 0 1]; +%! assert (isdefinite (A), 1) + +%!test +%! A = [2 -1 0; -1 2 -1; 0 -1 2]; +%! assert (isdefinite (A), 1) + +%!test +%! A = [1 0; 0 0]; +%! assert (isdefinite (A), 0) + +%!error isdefinite () +%!error isdefinite ([1 2; 3 4]) \ No newline at end of file
--- a/scripts/linear-algebra/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/linear-algebra/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -7,7 +7,6 @@ linear-algebra/cross.m \ linear-algebra/duplication_matrix.m \ linear-algebra/expm.m \ - linear-algebra/gmres.m \ linear-algebra/housh.m \ linear-algebra/isdefinite.m \ linear-algebra/ishermitian.m \
--- a/scripts/linear-algebra/null.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/linear-algebra/null.m Fri Aug 12 14:16:34 2011 -0400 @@ -77,3 +77,35 @@ endif endfunction + +%!test +%! A = 0; +%! assert(null(A), 1); + +%!test +%! A = 1; +%! assert(null(A), zeros(1,0)) + +%!test +%! A = [1 0; 0 1]; +%! assert(null(A), zeros(2,0)); + +%!test +%! A = [1 0; 1 0]; +%! assert(null(A), [0 1]') + +%!test +%! A = [1 1; 0 0]; +%! assert(null(A), [-1/sqrt(2) 1/sqrt(2)]', eps) + +%!test +%! tol = 1e-4; +%! A = [1 0; 0 tol-eps]; +%! assert(null(A,tol), [0 1]') + +%!test +%! tol = 1e-4; +%! A = [1 0; 0 tol+eps]; +%! assert(null(A,tol), zeros(2,0)); + +%!error null()
--- a/scripts/linear-algebra/orth.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/linear-algebra/orth.m Fri Aug 12 14:16:34 2011 -0400 @@ -39,6 +39,11 @@ if (nargin == 1 || nargin == 2) + if (isempty (A)) + retval = []; + return; + endif + [U, S, V] = svd (A); [rows, cols] = size (A);
--- a/scripts/linear-algebra/rank.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/linear-algebra/rank.m Fri Aug 12 14:16:34 2011 -0400 @@ -58,3 +58,54 @@ retval = sum (sigma > tolerance); endfunction + +%!test +%! A = [1 2 3 4 5 6 7; +%! 4 5 6 7 8 9 12; +%! 1 2 3.1 4 5 6 7; +%! 2 3 4 5 6 7 8; +%! 3 4 5 6 7 8 9; +%! 4 5 6 7 8 9 10; +%! 5 6 7 8 9 10 11]; +%! assert(rank(A),4); + +%!test +%! A = [1 2 3 4 5 6 7; +%! 4 5 6 7 8 9 12; +%! 1 2 3.0000001 4 5 6 7; +%! 4 5 6 7 8 9 12.00001; +%! 3 4 5 6 7 8 9; +%! 4 5 6 7 8 9 10; +%! 5 6 7 8 9 10 11]; +%! assert(rank(A),4); + +%!test +%! A = [1 2 3 4 5 6 7; +%! 4 5 6 7 8 9 12; +%! 1 2 3 4 5 6 7; +%! 4 5 6 7 8 9 12.00001; +%! 3 4 5 6 7 8 9; +%! 4 5 6 7 8 9 10; +%! 5 6 7 8 9 10 11]; +%! assert(rank(A),3); + +%!test +%! A = [1 2 3 4 5 6 7; +%! 4 5 6 7 8 9 12; +%! 1 2 3 4 5 6 7; +%! 4 5 6 7 8 9 12; +%! 3 4 5 6 7 8 9; +%! 4 5 6 7 8 9 10; +%! 5 6 7 8 9 10 11]; +%! assert(rank(A),3); + +%!test +%! A = eye(100); +%! assert(rank(A),100); + +%!test +%! A = [1, 2, 3; 1, 2.001, 3; 1, 2, 3.0000001]; +%! assert(rank(A),3) +%! assert(rank(A,0.0009),1) +%! assert(rank(A,0.0006),2) +%! assert(rank(A,0.00000002),3) \ No newline at end of file
--- a/scripts/miscellaneous/ans.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/ans.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,3 +28,7 @@ ## @noindent ## is evaluated, the value returned by @code{ans} is 25. ## @end defvr + +## Mark file as being tested. No real test needed for a documentation .m file +%!assert (1) +
--- a/scripts/miscellaneous/bug_report.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/bug_report.m Fri Aug 12 14:16:34 2011 -0400 @@ -43,3 +43,6 @@ puts ("\n"); endfunction + +## Mark file as being tested. No real test needed for this function. +%!assert (1)
--- a/scripts/miscellaneous/comma.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/comma.m Fri Aug 12 14:16:34 2011 -0400 @@ -21,3 +21,7 @@ ## Array index, function argument, or command separator. ## @seealso{semicolon} ## @end deftypefn + +## Mark file as being tested. No real test needed for a documentation .m file +%!assert (1) +
--- a/scripts/miscellaneous/fullfile.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/fullfile.m Fri Aug 12 14:16:34 2011 -0400 @@ -26,7 +26,7 @@ if (nargin > 0) ## Discard all empty arguments - varargin(cellfun (@isempty, varargin)) = []; + varargin(cellfun ("isempty", varargin)) = []; nargs = numel (varargin); if (nargs > 1) filename = varargin{1};
--- a/scripts/miscellaneous/getfield.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/getfield.m Fri Aug 12 14:16:34 2011 -0400 @@ -50,8 +50,8 @@ print_usage (); endif subs = varargin; - flds = cellfun (@ischar, subs); - idxs = cellfun (@iscell, subs); + flds = cellfun ("isclass", subs, "char"); + idxs = cellfun ("isclass", subs, "cell"); if (all (flds | idxs)) typs = merge (flds, {"."}, {"()"}); obj = subsref (s, struct ("type", typs, "subs", subs));
--- a/scripts/miscellaneous/info.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/info.m Fri Aug 12 14:16:34 2011 -0400 @@ -43,3 +43,6 @@ http://www.octave.org/bugs.html\n"); endfunction + +## Mark file as being tested. No real test needed for this function. +%! assert (1)
--- a/scripts/miscellaneous/ismac.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/ismac.m Fri Aug 12 14:16:34 2011 -0400 @@ -32,3 +32,5 @@ endfunction +%!error ismac (1); +%!assert (islogical (ismac ()));
--- a/scripts/miscellaneous/ispc.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/ispc.m Fri Aug 12 14:16:34 2011 -0400 @@ -31,3 +31,6 @@ endif endfunction + +%!error ispc (1); +%!assert (islogical (ispc ()));
--- a/scripts/miscellaneous/isunix.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/isunix.m Fri Aug 12 14:16:34 2011 -0400 @@ -31,3 +31,6 @@ endif endfunction + +%!error isunix (1); +%!assert (islogical (isunix ()));
--- a/scripts/miscellaneous/list_primes.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/list_primes.m Fri Aug 12 14:16:34 2011 -0400 @@ -83,3 +83,9 @@ endwhile endfunction + +%!test +%! assert (list_primes(), [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41,\ +%! 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]); +%! assert (list_primes(5), [2, 3, 5, 7, 11]); +
--- a/scripts/miscellaneous/ls.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/ls.m Fri Aug 12 14:16:34 2011 -0400 @@ -63,7 +63,7 @@ retval = strvcat (regexp (output, '\S+', 'match'){:}); endif else - error ("ls: command exited abnormally with status %d", status); + error ("ls: command exited abnormally with status %d\n", status); endif else
--- a/scripts/miscellaneous/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -61,7 +61,6 @@ miscellaneous/tar.m \ miscellaneous/tempdir.m \ miscellaneous/tempname.m \ - miscellaneous/unimplemented.m \ miscellaneous/unix.m \ miscellaneous/unpack.m \ miscellaneous/untar.m \
--- a/scripts/miscellaneous/news.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/news.m Fri Aug 12 14:16:34 2011 -0400 @@ -36,3 +36,7 @@ endif endfunction + + +## Remove from test statistics. No real tests possible +%!assert (1)
--- a/scripts/miscellaneous/paren.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/paren.m Fri Aug 12 14:16:34 2011 -0400 @@ -21,3 +21,7 @@ ## @deftypefnx {Operator} {} ) ## Array index or function argument delimeter. ## @end deftypefn + +## Mark file as being tested. No real test needed for a documentation .m file +%!assert (1) +
--- a/scripts/miscellaneous/private/__xzip__.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/private/__xzip__.m Fri Aug 12 14:16:34 2011 -0400 @@ -112,10 +112,10 @@ endfunction function [d, f] = myfileparts (files) - [d, f, ext] = cellfun (@(x) fileparts (x), files, "uniformoutput", false); + [d, f, ext] = cellfun ("fileparts", files, "uniformoutput", false); f = cellfun (@(x, y) sprintf ("%s%s", x, y), f, ext, "uniformoutput", false); - idx = cellfun (@isdir, files); + idx = cellfun ("isdir", files); d(idx) = ""; f(idx) = files(idx); endfunction
--- a/scripts/miscellaneous/semicolon.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/semicolon.m Fri Aug 12 14:16:34 2011 -0400 @@ -21,3 +21,7 @@ ## Array row or command separator. ## @seealso{comma} ## @end deftypefn + +## Mark file as being tested. No real test needed for a documentation .m file +%!assert (1) +
--- a/scripts/miscellaneous/setfield.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/setfield.m Fri Aug 12 14:16:34 2011 -0400 @@ -50,8 +50,8 @@ endif subs = varargin(1:end-1); rhs = varargin{end}; - flds = cellfun (@ischar, subs); - idxs = cellfun (@iscell, subs); + flds = cellfun ("isclass", subs, "char"); + idxs = cellfun ("isclass", subs, "cell"); if (all (flds | idxs)) typs = merge (flds, {"."}, {"()"}); obj = subsasgn (obj, struct ("type", typs, "subs", subs), rhs);
--- a/scripts/miscellaneous/swapbytes.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/swapbytes.m Fri Aug 12 14:16:34 2011 -0400 @@ -32,6 +32,7 @@ ## @end deftypefn function y = swapbytes (x) + if (nargin != 1) print_usage (); endif @@ -53,4 +54,11 @@ y = reshape (typecast (reshape (typecast (x(:), "uint8"), nb, numel (x)) ([nb : -1 : 1], :) (:), clx), size(x)); endif + endfunction + + +%!assert (double (swapbytes (uint16 (1:4))), [256 512 768 1024]) +%!error (swapbytes ()) +%!error (swapbytes (1, 2)) +
--- a/scripts/miscellaneous/symvar.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/symvar.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,3 +28,6 @@ function args = symvar (s) args = argnames (inline (s)); endfunction + +## This function is tested by the tests for argnames(). +%!assert (1)
--- a/scripts/miscellaneous/unimplemented.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,430 +0,0 @@ -## Copyright (C) 2010-2011 John W. Eaton -## Copyright (C) 2010 VZLU Prague -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} unimplemented () -## Undocumented internal function. -## @end deftypefn - -function txt = unimplemented (fcn) - - is_matlab_function = true; - - ## Some smarter cases, add more as needed. - switch (fcn) - - case "quad2d" - txt = ["quad2d is not implemented. Consider using dblquad."]; - - case "gsvd" - txt = ["gsvd is not currently part of Octave. See the linear-algebra",... - "package at @url{http://octave.sf.net/linear-algebra/}."]; - - case "linprog" - txt = ["Octave does not currently provide linprog. ",... - "Linear programming problems may be solved using @code{glpk}. ",... - "Try @code{help glpk} for more info."]; - - case {"ode113", "ode15i", "ode15s", "ode23", "ode23s", "ode23t", "ode45", "odeget", "odeset"} - txt = ["Octave provides lsode for solving differential equations. ",... - "For more information try @code{help lsode}. ",... - "Matlab-compatible ODE functions are provided by the odepkg package. ",... - "See @url{http://octave.sf.net/odepkg/}."]; - - otherwise - if (ismember (fcn, missing_functions ())) - txt = sprintf ("the `%s' function is not yet implemented in Octave", fcn); - else - is_matlab_function = false; - txt = ""; - endif - endswitch - - if (is_matlab_function) - txt = [txt, "\n\n@noindent\nPlease read ",... - "@url{http://www.octave.org/missing.html} to learn how ",... - "you can contribute missing functionality."]; - txt = __makeinfo__ (txt); - endif - - if (nargout == 0) - warning ("Octave:missing-function", "%s", txt); - endif - -endfunction - -function list = missing_functions () - persistent list = { - "DelaunayTri", - "MException", - "RandStream", - "TriRep", - "TriScatteredInterp", - "addpref", - "align", - "alim", - "alpha", - "alphamap", - "annotation", - "audiodevinfo", - "audioplayer", - "audiorecorder", - "aufinfo", - "auread", - "auwrite", - "avifile", - "aviinfo", - "aviread", - "bar3", - "bar3h", - "bench", - "betaincinv", - "bicg", - "bicgstabl", - "brush", - "builddocsearchdb", - "bvp4c", - "bvp5c", - "bvpget", - "bvpinit", - "bvpset", - "bvpxtend", - "callSoapService", - "calllib", - "camdolly", - "cameratoolbar", - "camlight", - "camlookat", - "camorbit", - "campan", - "campos", - "camproj", - "camroll", - "camtarget", - "camup", - "camva", - "camzoom", - "cdf2rdf", - "cdfepoch", - "cdfinfo", - "cdfread", - "cdfwrite", - "cellplot", - "checkin", - "checkout", - "cholinc", - "clearvars", - "clipboard", - "cmopts", - "cmpermute", - "cmunique", - "colordef", - "colormapeditor", - "commandhistory", - "commandwindow", - "condeig", - "coneplot", - "contourslice", - "copyobj", - "createClassFromWsdl", - "createSoapMessage", - "customverctrl", - "daqread", - "datacursormode", - "datatipinfo", - "dbmex", - "dde23", - "ddeget", - "ddesd", - "ddeset", - "decic", - "depdir", - "depfun", - "deval", - "dialog", - "dither", - "docopt", - "docsearch", - "dragrect", - "dynamicprops", - "echodemo", - "ellipj", - "ellipke", - "erfcinv", - "errordlg", - "evalc", - "exifread", - "expint", - "export2wsdlg", - "figurepalette", - "filebrowser", - "fill3", - "findfigs", - "fitsinfo", - "fitsread", - "flow", - "fminsearch", - "frame2im", - "freqspace", - "funm", - "gallery", - "gammaincinv", - "gco", - "getframe", - "getpixelposition", - "getpref", - "gmres", - "grabcode", - "graymon", - "gsvd", - "guidata", - "guide", - "guihandles", - "handle", - "hdf", - "hdf5", - "hdf5info", - "hdf5read", - "hdf5write", - "hdfinfo", - "hdfread", - "hdftool", - "helpbrowser", - "helpdesk", - "helpdlg", - "helpwin", - "hgexport", - "hgload", - "hgsave", - "hgsetget", - "hgtransform", - "hostid", - "ilu", - "im2frame", - "im2java", - "imapprox", - "imformats", - "import", - "importdata", - "inmem", - "inputParser", - "inputdlg", - "inspect", - "instrfind", - "instrfindall", - "interpstreamspeed", - "iscom", - "isinterface", - "isjava", - "isocaps", - "ispref", - "isstudent", - "javaArray", - "javaMethod", - "javaMethodEDT", - "javaObject", - "javaObjectEDT", - "javaaddpath", - "javachk", - "javaclasspath", - "javarmpath", - "ldl", - "libfunctions", - "libfunctionsview", - "libisloaded", - "libpointer", - "libstruct", - "light", - "lightangle", - "lighting", - "linkaxes", - "linkdata", - "linsolve", - "listdlg", - "listfonts", - "loadlibrary", - "lscov", - "lsqr", - "makehgtform", - "material", - "matlabrc", - "maxNumCompThreads", - "memmapfile", - "memory", - "metaclass", - "methodsview", - "minres", - "mlint", - "mlintrpt", - "mmfileinfo", - "mmreader", - "movegui", - "movie", - "movie2avi", - "msgbox", - "multibandread", - "multibandwrite", - "native2unicode", - "noanimate", - "ode113", - "ode15i", - "ode15s", - "ode23", - "ode23s", - "ode23t", - "ode23tb", - "ode45", - "odefile", - "odeget", - "odeset", - "odextend", - "open", - "openfig", - "opengl", - "openvar", - "ordeig", - "ordqz", - "ordschur", - "padecoef", - "pagesetupdlg", - "pan", - "parseSoapResponse", - "path2rc", - "pathtool", - "pcode", - "pdepe", - "pdeval", - "playshow", - "plotbrowser", - "plotedit", - "plottools", - "polyeig", - "prefdir", - "preferences", - "printdlg", - "printopt", - "printpreview", - "profile", - "profsave", - "propedit", - "propertyeditor", - "publish", - "qmr", - "quad2d", - "questdlg", - "rbbox", - "recycle", - "reducepatch", - "reducevolume", - "resample", - "reset", - "rgbplot", - "rmpref", - "root", - "rotate", - "rotate3d", - "rsf2csf", - "selectmoveresize", - "sendmail", - "serial", - "setpixelposition", - "setpref", - "showplottool", - "shrinkfaces", - "smooth3", - "snapnow", - "sound", - "soundsc", - "ss2tf", - "stream2", - "stream3", - "streamline", - "streamparticles", - "streamribbon", - "streamslice", - "streamtube", - "strings", - "subvolume", - "superclasses", - "support", - "surf2patch", - "symmlq", - "syntax", - "tetramesh", - "texlabel", - "textwrap", - "tfqmr", - "timer", - "timerfind", - "timerfindall", - "timeseries", - "toolboxdir", - "tscollection", - "tstool", - "uibuttongroup", - "uicontextmenu", - "uicontrol", - "uigetpref", - "uiimport", - "uiopen", - "uipanel", - "uipushtool", - "uiresume", - "uisave", - "uisetcolor", - "uisetfont", - "uisetpref", - "uistack", - "uitable", - "uitoggletool", - "uitoolbar", - "uiwait", - "undocheckout", - "unicode2native", - "unloadlibrary", - "unmesh", - "usejava", - "userpath", - "validateattributes", - "verLessThan", - "viewmtx", - "visdiff", - "volumebounds", - "waitbar", - "waitfor", - "warndlg", - "waterfall", - "wavfinfo", - "wavplay", - "wavrecord", - "web", - "whatsnew", - "wk1finfo", - "wk1read", - "wk1write", - "workspace", - "xlsfinfo", - "xlsread", - "xlswrite", - "xmlread", - "xmlwrite", - "xslt", - "zoom", - }; -endfunction
--- a/scripts/miscellaneous/warning_ids.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/warning_ids.m Fri Aug 12 14:16:34 2011 -0400 @@ -284,3 +284,6 @@ function warning_ids () help ("warning_ids"); endfunction + +## Remove from test statistics. No real tests possible +%!assert (1)
--- a/scripts/miscellaneous/what.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/miscellaneous/what.m Fri Aug 12 14:16:34 2011 -0400 @@ -90,7 +90,7 @@ if (length (f) > 0) printf ("%s %s:\n\n", msg, p); - maxlen = max (cellfun (@length, f)); + maxlen = max (cellfun ("length", f)); ncols = max (1, floor (terminal_size()(2) / (maxlen + 3))); fmt = ""; for i = 1: ncols
--- a/scripts/path/matlabroot.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/path/matlabroot.m Fri Aug 12 14:16:34 2011 -0400 @@ -31,5 +31,5 @@ endfunction +%!assert (matlabroot(), OCTAVE_HOME()) -
--- a/scripts/pkg/pkg.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/pkg/pkg.m Fri Aug 12 14:16:34 2011 -0400 @@ -20,8 +20,10 @@ ## -*- texinfo -*- ## @deftypefn {Command} {} pkg @var{command} @var{pkg_name} ## @deftypefnx {Command} {} pkg @var{command} @var{option} @var{pkg_name} -## This command interacts with the package manager. Different actions will -## be taken depending on the value of @var{command}. +## Manage packages (groups of add-on functions) for Octave. Different actions +## are available depending on the value of @var{command}. +## +## Available commands: ## ## @table @samp ## @@ -40,34 +42,44 @@ ## ## @table @code ## @item -nodeps -## The package manager will disable the dependency checking. That way it -## is possible to install a package even if it depends on another package -## that's not installed on the system. @strong{Use this option with care.} +## The package manager will disable dependency checking. With this option it +## is possible to install a package even when it depends on another package +## which is not installed on the system. @strong{Use this option with care.} ## ## @item -noauto ## The package manager will not automatically load the installed package -## when starting Octave, even if the package requests that it is. +## when starting Octave. This overrides any setting within the package. ## ## @item -auto ## The package manager will automatically load the installed package when -## starting Octave, even if the package requests that it isn't. +## starting Octave. This overrides any setting within the package. ## ## @item -local -## A local installation is forced, even if the user has system privileges. +## A local installation (package available only to current user) is forced, +## even if the user has system privileges. ## ## @item -global -## A global installation is forced, even if the user doesn't normally have -## system privileges +## A global installation (package available to all users) is forced, even if +## the user doesn't normally have system privileges. ## ## @item -forge ## Install a package directly from the Octave-Forge repository. This ## requires an internet connection and the cURL library. ## ## @item -verbose -## The package manager will print the output of all of the commands that are -## performed. +## The package manager will print the output of all commands as +## they are performed. ## @end table ## +## @item update +## Check installed Octave-Forge pacakages against repository and update any +## outdated items. This requires an internet connection and the cURL library. +## Usage: +## +## @example +## pkg update +## @end example +## ## @item uninstall ## Uninstall named packages. For example, ## @@ -90,47 +102,53 @@ ## ## @noindent ## adds the @code{image} package to the path. It is possible to load all -## installed packages at once with the command +## installed packages at once with the keyword @samp{all}. Usage: ## ## @example ## pkg load all ## @end example ## ## @item unload -## Removes named packages from the path. After unloading a package it is -## no longer possible to use the functions provided by the package. -## This command behaves like the @code{load} command. +## Remove named packages from the path. After unloading a package it is +## no longer possible to use the functions provided by the package. It is +## possible to unload all installed packages at once with the keyword +## @samp{all}. Usage: +## +## @example +## pkg unload all +## @end example ## ## @item list -## Show a list of the currently installed packages. By requesting one or two -## output argument it is possible to get a list of the currently installed -## packages. For example, +## Show the list of currently installed packages. For example, ## ## @example -## installed_packages = pkg list; +## installed_packages = pkg ("list") ## @end example ## ## @noindent ## returns a cell array containing a structure for each installed package. -## The command ## +## If two output arguments are requested @code{pkg} splits the list of +## installed packages into those which were installed by the current user, +## and those which were installed by the system administrator. +## ## @example -## [@var{user_packages}, @var{system_packages}] = pkg list +## [user_packages, system_packages] = pkg ("list") ## @end example ## -## @noindent -## splits the list of installed packages into those who are installed by -## the current user, and those installed by the system administrator. +## The option '-forge' lists packages available at the Octave-Forge repository. +## This requires an internet connection and the cURL library. For example: ## -## The option '-forge' lists packages available at the Octave-Forge repository. -## This requires an internet connection and the cURL library. +## @example +## oct_forge_pkgs = pkg ("list", "-forge") +## @end example ## ## @item describe ## Show a short description of the named installed packages, with the option -## '-verbose' also list functions provided by the package, e.g.: +## '-verbose' also list functions provided by the package. For example, ## ## @example -## pkg describe -verbose all +## pkg describe -verbose all ## @end example ## ## @noindent @@ -140,7 +158,7 @@ ## output rather than printed on screen: ## ## @example -## desc = pkg ("describe", "secs1d", "image") +## desc = pkg ("describe", "secs1d", "image") ## @end example ## ## @noindent @@ -148,7 +166,7 @@ ## error, unless a second output is requested: ## ## @example -## [ desc, flag] = pkg ("describe", "secs1d", "image") +## [desc, flag] = pkg ("describe", "secs1d", "image") ## @end example ## ## @noindent @@ -170,20 +188,20 @@ ## output argument. For example: ## ## @example -## p = pkg prefix +## pfx = pkg ("prefix") ## @end example ## ## The location in which to install the architecture dependent files can be -## independent specified with an addition argument. For example: +## independently specified with an addition argument. For example: ## ## @example ## pkg prefix ~/my_octave_packages ~/my_arch_dep_pkgs ## @end example ## ## @item local_list -## Set the file in which to look for information on the locally +## Set the file in which to look for information on locally ## installed packages. Locally installed packages are those that are -## typically available only to the current user. For example: +## available only to the current user. For example: ## ## @example ## pkg local_list ~/.octave_packages @@ -196,9 +214,9 @@ ## @end example ## ## @item global_list -## Set the file in which to look for, for information on the globally +## Set the file in which to look for information on globally ## installed packages. Globally installed packages are those that are -## typically available to all users. For example: +## available to all users. For example: ## ## @example ## pkg global_list /usr/share/octave/octave_packages @@ -210,21 +228,8 @@ ## pkg global_list ## @end example ## -## @item rebuild -## Rebuilds the package database from the installed directories. This can -## be used in cases where for some reason the package database is corrupted. -## It can also take the @option{-auto} and @option{-noauto} options to allow the -## autoloading state of a package to be changed. For example, -## -## @example -## pkg rebuild -noauto image -## @end example -## -## @noindent -## will remove the autoloading status of the image package. -## ## @item build -## Builds a binary form of a package or packages. The binary file produced +## Build a binary form of a package or packages. The binary file produced ## will itself be an Octave package that can be installed normally with ## @code{pkg}. The form of the command to build a binary package is ## @@ -236,7 +241,21 @@ ## where @code{builddir} is the name of a directory where the temporary ## installation will be produced and the binary packages will be found. ## The options @option{-verbose} and @option{-nodeps} are respected, while -## the other options are ignored. +## all other options are ignored. +## +## @item rebuild +## Rebuild the package database from the installed directories. This can +## be used in cases where the package database has been corrupted. +## It can also take the @option{-auto} and @option{-noauto} options to allow the +## autoloading state of a package to be changed. For example, +## +## @example +## pkg rebuild -noauto image +## @end example +## +## @noindent +## will remove the autoloading status of the image package. +## ## @end table ## @end deftypefn @@ -267,7 +286,8 @@ available_actions = {"list", "install", "uninstall", "load", ... "unload", "prefix", "local_list", ... - "global_list", "rebuild", "build","describe"}; + "global_list", "rebuild", "build", ... + "describe", "update"}; ## Handle input if (length (varargin) == 0 || ! iscellstr (varargin)) print_usage (); @@ -349,8 +369,8 @@ unwind_protect if (octave_forge) - [urls, local_files] = cellfun (@get_forge_download, files, "uniformoutput", false); - [files, succ] = cellfun (@urlwrite, urls, local_files, "uniformoutput", false); + [urls, local_files] = cellfun ("get_forge_download", files, "uniformoutput", false); + [files, succ] = cellfun ("urlwrite", urls, local_files, "uniformoutput", false); succ = [succ{:}]; if (! all (succ)) i = find (! succ, 1); @@ -362,7 +382,7 @@ global_list, global_install); unwind_protect_cleanup - cellfun (@unlink, local_files); + cellfun ("unlink", local_files); end_unwind_protect case "uninstall" @@ -492,6 +512,21 @@ error ("you can request at most two outputs when calling 'pkg describe'"); endswitch + case "update" + if (nargout == 0) + installed_pkgs_lst = installed_packages (local_list, global_list); + for i = 1:length (installed_pkgs_lst) + installed_pkg_name = installed_pkgs_lst{i}.name; + installed_pkg_version = installed_pkgs_lst{i}.version; + forge_pkg_version = get_forge_pkg (installed_pkg_name); + if (compare_versions (forge_pkg_version, installed_pkg_version, ">")) + feval (@pkg, "install", "-forge", installed_pkg_name); + endif + endfor + else + error ("no output arguments available"); + endif + otherwise error ("you must specify a valid action for 'pkg'. See 'help pkg' for details"); endswitch @@ -1383,7 +1418,7 @@ if (isempty (filenames)) idx = []; else - idx = cellfun (@is_architecture_dependent, filenames); + idx = cellfun ("is_architecture_dependent", filenames); endif archdependent = filenames (idx); archindependent = filenames (!idx);
--- a/scripts/plot/__fltk_ginput__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -## Copyright (C) 2010-2011 Shai Ayal -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __fltk_ginput__ (@var{f}, @var{n}) -## Undocumented internal function. -## @end deftypefn - -## This is ginput.m implementation for fltk. - -## FIXME -- Key presses cannot toggle menu items nor hotkey functionality -## (grid, autoscale) during ginput! - -function [x, y, button] = __fltk_ginput__ (f, n = -1) - - if (isempty (get (f, "currentaxes"))) - error ("ginput: must have at least one axes"); - endif - - x = y = button = []; - ginput_aggregator (0, 0, 0, 0); - - unwind_protect - - orig_windowbuttondownfcn = get (f, "windowbuttondownfcn"); - set (f, "windowbuttondownfcn", @ginput_windowbuttondownfcn); - - orig_ginput_keypressfcn = get (f, "keypressfcn"); - set (f, "keypressfcn", @ginput_keypressfcn); - - while (true) - __fltk_redraw__ (); - - ## Release CPU. - sleep (0.01); - - [x, y, n0, button] = ginput_aggregator (-1, 0, 0, 0); - if (n0 == n || n0 < 0) - break; - endif - endwhile - - unwind_protect_cleanup - set (f, "windowbuttondownfcn", orig_windowbuttondownfcn); - set (f, "keypressfcn", orig_ginput_keypressfcn); - end_unwind_protect - -endfunction - -function [x, y, n, button] = ginput_aggregator (mode, xn, yn, btn) - persistent x y n button; - - if (mode == 0) - ## Initialize. - x = []; - y = []; - button = []; - n = 0; - elseif (mode == 1) - ## Accept mouse button or key press. - x = [x; xn]; - y = [y; yn]; - button = [button; btn]; - n += 1; - elseif (mode == 2) - ## The end due to Enter. - n = -1; - endif -endfunction - -function ginput_windowbuttondownfcn (src, data) - point = get (get (src,"currentaxes"), "currentpoint"); - ## FIXME -- How to get the actual mouse button pressed (1,2,3) into - ## "button"? - button = 1; - ginput_aggregator (1, point(1,1), point(2,1), button); -endfunction - -function ginput_keypressfcn (src, evt) - point = get (get (src, "currentaxes"), "currentpoint"); - ## FIXME -- use evt.Key or evt.Character? - key = evt.Key; - if (key == 10) - ## Enter key. - ginput_aggregator (2, point(1,1), point(2,1), key); - else - ginput_aggregator (1, point(1,1), point(2,1), key); - endif -endfunction -
--- a/scripts/plot/__fltk_print__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -## Copyright (C) 2010-2011 Shai Ayal -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} __fltk_print__ (@var{@dots{}}) -## Undocumented internal function. -## @end deftypefn - -function opts = __fltk_print__ (opts) - - dos_shell = (ispc () && ! isunix ()); - - figure (opts.figure); - drawnow ("expose"); - __fltk_redraw__ (); - - if (! isempty (opts.fig2dev_binary)) - ## fig2dev is prefered for conversion to emf - fig2dev_devices = {"pstex", "mf", "emf"}; - else - fig2dev_devices = {"pstex", "mf"}; - endif - - gl2ps_device = {}; - pipeline = {}; - switch (lower (opts.devopt)) - case {"eps", "eps2", "epsc", "epsc2"} - ## format GL2PS_EPS - gl2ps_device = {"eps"}; - ## FIXME - use epstool to tighten bbox and provide preview. - pipeline = {opts.epstool_cmd(opts, "-", opts.name)}; - case {"epslatex", "pslatex", "pdflatex", "epslatexstandalone", ... - "pslatexstandalone", "pdflatexstandalone"} - ## format GL2PS_TEX - n = find (opts.devopt == "l", 1); - suffix = opts.devopt(1:n-1); - dot = find (opts.name == ".", 1, "last"); - if ((! isempty (dot)) - && any (strcmpi (opts.name(dot:end), ... - {".eps", ".ps", ".pdf", ".tex", "."}))) - name = opts.name(1:dot-1); - if (dot < numel (opts.name) - && any (strcmpi (opts.name(dot+1:end), {"eps", "ps", "pdf"}))) - ## If user provides eps/ps/pdf suffix, use it. - suffix = opts.name(dot+1:end); - endif - elseif (dot == numel (opts.name)) - name = opts.name; - endif - gl2ps_device = {sprintf("%snotxt", lower (suffix))}; - gl2ps_device{2} = "tex"; - if (dos_shell) - ## FIXME - this will only work on MinGW with the MSYS shell - pipeline = {sprintf("cat > %s-inc.%s", name, suffix)}; - pipeline{2} = sprintf ("cat > %s.tex", name); - else - pipeline = {sprintf("cat > %s-inc.%s", name, suffix)}; - pipeline{2} = sprintf ("cat > %s.tex", name); - endif - case "tikz" - ## format GL2PS_PGF - gl2ps_device = {"pgf"}; - pipeline = {sprintf("cat > %s", opts.name)}; - case "svg" - ## format GL2PS_SVG - gl2ps_device = {"svg"}; - pipeline = {sprintf("cat > %s", opts.name)}; - case fig2dev_devices - cmd_pstoedit = opts.pstoedit_cmd (opts, "fig"); - cmd_fig2dev = opts.fig2dev_cmd (opts, opts.devopt); - if (strcmp (opts.devopt, "pstex")) - [~, ~, ext] = fileparts (opts.name); - if (any (strcmpi (ext, {".ps", ".tex", "."}))) - opts.name = opts.name(1:end-numel(ext)); - endif - opts.name = strcat (opts.name, ".ps"); - cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name); - gl2ps_device = {"eps"}; - pipeline = {cmd}; - cmd_fig2dev = opts.fig2dev_cmd (opts, "pstex_t"); - gl2ps_device{2} = "eps"; - pipeline{2} = sprintf ("%s | %s > %s", cmd_pstoedit, - cmd_fig2dev, strrep(opts.name, ".ps", ".tex")); - else - cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name); - gl2ps_device = {"eps"}; - pipeline = {cmd}; - endif - case "aifm" - cmd = opts.pstoedit_cmd (opts, "ps2ai"); - gl2ps_device = {"eps"}; - pipeline = {sprintf("%s > %s", cmd, opts.name)}; - case {"dxf", "emf", "fig", "hpgl"} - cmd = opts.pstoedit_cmd (opts); - gl2ps_device = {"eps"}; - pipeline = {sprintf("%s > %s", cmd, opts.name)}; - case {"corel", "gif"} - error ("print:unsupporteddevice", - "print.m: %s output is not available for the FLTK graphics toolkit", - upper (opts.devopt)); - case opts.ghostscript.device - opts.ghostscript.source = "-"; - opts.ghostscript.output = opts.name; - if (opts.send_to_printer) - opts.unlink(strcmp (opts.unlink, opts.ghostscript.output)) = []; - opts.ghostscript.output = "-"; - endif - [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript); - if (opts.send_to_printer || isempty (opts.name)) - cmd_lpr = opts.lpr_cmd (opts); - cmd = sprintf("%s | %s", cmd_gs, cmd_lpr); - else - cmd = sprintf("%s", cmd_gs); - endif - if (! isempty (cmd_cleanup)) - gl2ps_device = {"eps"}; - if (dos_shell) - pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)}; - else - pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)}; - endif - else - gl2ps_device = {"eps"}; - pipeline = {cmd}; - endif - otherwise - error (sprintf ("print:no%soutput", opts.devopt), - "print.m: %s output is not available for GL2PS output", - upper (opts.devopt)); - endswitch - - opts.pipeline = pipeline; - - for n = 1:numel(pipeline) - if (opts.debug) - fprintf ("fltk-pipeline: '%s'\n", pipeline{n}); - endif - drawnow (gl2ps_device{n}, strcat('|',pipeline{n})); - endfor - - if (! isempty (strfind (opts.devopt, "standalone"))) - opts.latex_standalone (opts); - endif - -endfunction -
--- a/scripts/plot/__gnuplot_get_var__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,161 +0,0 @@ -## Copyright (C) 2009-2011 Ben Abbott -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {@var{value} =} __gnuplot_get_var__ (@var{h}, @var{name}, @var{fmt}) -## Undocumented internal function. -## @end deftypefn - -## Author: Ben Abbott <bpabbott@mac.com> -## Created: 2009-02-07 - -function gp_var_value = __gnuplot_get_var__ (h, gp_var_name, fmt) - - if (nargin == 0) - h = gcf (); - endif - if (nargin < 2) - print_usage (); - endif - if (nargin < 3) - fmt = ''; - endif - - if (numel (h) == 1 && isfigure (h)) - if (isempty (get (gcf, "__plot_stream__"))) - ostream = __gnuplot_open_stream__ (2, h); - else - ostream = get (h, "__plot_stream__"); - endif - else - ostream = h; - endif - if (numel (ostream) < 1) - error ("__gnuplot_get_var__: stream to gnuplot not open"); - elseif (ispc ()) - if (numel (ostream) == 1) - error ("__gnuplot_get_var__: Need mkfifo that is not implemented under Windows"); - endif - use_mkfifo = false; - istream = ostream(2); - ostream = ostream(1); - else - use_mkfifo = true; - ostream = ostream(1); - endif - - if (use_mkfifo) - gpin_name = tmpnam (); - - ## Mode: 6*8*8 == 0600 - [err, msg] = mkfifo (gpin_name, 6*8*8); - - if (err != 0) - error ("__gnuplot_get_var__: Can not make fifo (%s)", msg); - endif - endif - - gp_var_name = strtrim (gp_var_name); - n = min (strfind (gp_var_name, " "), strfind (gp_var_name, ",")) - 1; - if (isempty (n)) - n = numel (gp_var_name); - endif - - unwind_protect - - ## Notes: Variables may be undefined if user closes gnuplot by "q" - ## or Alt-F4. Further, this abrupt close also requires the leading - ## "\n" on the next line. - if (use_mkfifo) - fprintf (ostream, "\nset print \"%s\";\n", gpin_name); - fflush (ostream); - [gpin, err] = fopen (gpin_name, "r"); - if (err != 0) - ## Try a second time, and then give an error. - [gpin, err] = fopen (gpin_name, "r"); - endif - if (err != 0) - error ("__gnuplot_get_var__: can not open fifo"); - endif - gp_cmd = sprintf ("\nif (exists(\"%s\")) print %s; else print NaN\n", - gp_var_name(1:n), gp_var_name); - fputs (ostream, gp_cmd); - - ## Close output file, to force it to be flushed - fputs (ostream, "set print;\n"); - fflush (ostream); - - ## Now read from fifo. - reading = true; - str = {}; - while (reading) - str{end+1} = fgets (gpin); - if (isnumeric (str{end}) && (str{end} == -1)) - reading = false; - str = str(1:(end-1)); - endif - endwhile - str = strcat (str{:}); - fclose (gpin); - else - ## Direct gnuplot to print to <STDOUT> - fprintf (ostream, "set print \"-\";\n"); - fflush (ostream); - gp_cmd = sprintf ("\nif (exists(\"%s\")) print \"OCTAVE: \", %s; else print NaN\n", - gp_var_name(1:n), gp_var_name); - fputs (ostream, gp_cmd); - fflush (ostream); - ## Direct gnuplot to print to <STDERR> - fputs (ostream, "set print;\n"); - fflush (ostream); - - str = {}; - while (isempty (str)) - str = char (fread (istream)'); - if (isempty (str)) - sleep (0.05); - else - str = regexp (str, 'OCTAVE:.*', "match"); - str = str{end}(8:end); - endif - fclear (istream); - endwhile - endif - - ## Strip out EOLs and the continuation character "|" - str(str=="\n") = ""; - str(str=="\r") = ""; - n_continue = strfind (str, " \\ "); - if (! isempty (n_continue)) - str(n_continue+1) = ""; - endif - - if (isempty (fmt)) - gp_var_value = strtrim (str); - else - gp_var_value = sscanf (str, fmt); - endif - - unwind_protect_cleanup - if (use_mkfifo) - unlink (gpin_name); - endif - end_unwind_protect - -endfunction -
--- a/scripts/plot/__gnuplot_ginput__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,154 +0,0 @@ -## Copyright (C) 2004-2011 Petr Mikulik -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __gnuplot_ginput__ (@var{f}, @var{n}) -## Undocumented internal function. -## @end deftypefn - -## This is ginput.m implementation for gnuplot and X11. -## It requires gnuplot 4.1 and later. - -## This file initially bore the copyright statement -## Petr Mikulik -## History: June 2006; August 2005; June 2004; April 2004 -## License: public domain - -function [x, y, button] = __gnuplot_ginput__ (f, n) - - ostream = get (f, "__plot_stream__"); - if (numel (ostream) < 1) - error ("ginput: stream to gnuplot not open"); - elseif (ispc ()) - if (numel (ostream) == 1) - error ("ginput: Need mkfifo that is not implemented under Windows"); - endif - use_mkfifo = false; - istream = ostream(2); - ostream = ostream(1); - else - use_mkfifo = true; - ostream = ostream(1); - endif - - if (compare_versions (__gnuplot_version__ (), "4.0", "<=")) - error ("ginput: version %s of gnuplot not supported", gnuplot_version ()); - endif - - if (nargin == 1) - x = zeros (100, 1); - y = zeros (100, 1); - button = zeros (100, 1); - else - x = zeros (n, 1); - y = zeros (n, 1); - button = zeros (n, 1); - endif - - if (use_mkfifo) - gpin_name = tmpnam (); - - ##Mode: 6*8*8 == 0600 - [err, msg] = mkfifo (gpin_name, 6*8*8); - - if (err != 0) - error ("ginput: Can not open fifo (%s)", msg); - endif - endif - - unwind_protect - - k = 0; - while (true) - k++; - - ## Notes: MOUSE_* can be undefined if user closes gnuplot by "q" - ## or Alt-F4. Further, this abrupt close also requires the leading - ## "\n" on the next line. - if (use_mkfifo) - fprintf (ostream, "set print \"%s\";\n", gpin_name); - fflush (ostream); - [gpin, err] = fopen (gpin_name, "r"); - if (err != 0) - error ("ginput: Can not open fifo (%s)", msg); - endif - fputs (ostream, "pause mouse any;\n\n"); - fputs (ostream, "\nif (exists(\"MOUSE_KEY\") && exists(\"MOUSE_X\")) print MOUSE_X, MOUSE_Y, MOUSE_KEY; else print \"0 0 -1\"\n"); - - ## Close output file, to force it to be flushed - fputs (ostream, "set print;\n"); - fflush (ostream); - - ## Now read from fifo. - [x(k), y(k), button(k), count] = fscanf (gpin, "%f %f %d", "C"); - fclose (gpin); - else - fprintf (ostream, "set print \"-\";\n"); - fflush (ostream); - fputs (ostream, "pause mouse any;\n\n"); - fputs (ostream, "\nif (exists(\"MOUSE_KEY\") && exists(\"MOUSE_X\")) print \"OCTAVE: \", MOUSE_X, MOUSE_Y, MOUSE_KEY; else print \"0 0 -1\"\n"); - - ## Close output file, to force it to be flushed - fputs (ostream, "set print;\n"); - fflush (ostream); - - str = {}; - while (isempty (str)) - str = char (fread (istream)'); - if (isempty (str)) - sleep (0.05); - else - str = regexp (str, 'OCTAVE:\s+[-+.\d]+\s+[-+.\d]+\s+\d*', 'match'); - endif - fclear (istream); - endwhile - [x(k), y(k), button(k), count] = sscanf (str{end}(8:end), "%f %f %d", "C"); - endif - - if ([x(k), y(k), button(k)] == [0, 0, -1]) - ## Mousing not active (no plot yet). - break; - endif - - if (nargin > 1) - ## Input argument n was given => stop when k == n. - if (k == n) - break; - endif - else - ## Input argument n not given => stop when hitting a return key. - ## if (button(k) == 0x0D || button(k) == 0x0A) - ## ## hit Return or Enter - if (button(k) == 0x0D) - ## hit Return - x(k:end) = []; - y(k:end) = []; - button(k:end) = []; - break; - endif - endif - endwhile - - unwind_protect_cleanup - if (use_mkfifo) - unlink (gpin_name); - endif - end_unwind_protect - -endfunction -
--- a/scripts/plot/__gnuplot_has_feature__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -## Copyright (C) 2009-2011 Ben Abbott -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {@var{has_feature} =} __gnuplot_has_feature__ (@var{feature}) -## Undocumented internal function. -## @end deftypefn - -## Author: Ben Abbott <bpabbott@mac.com> -## Created: 2009-01-27 - -function res = __gnuplot_has_feature__ (feature) - persistent features has_features - features = {"x11_figure_position", - "wxt_figure_size", - "transparent_patches", - "transparent_surface", - "epslatex_implies_eps_filesuffix", - "epslatexstandalone_terminal", - "screen_coordinates_for_{lrtb}margin", - "variable_GPVAL_TERMINALS", - "key_has_font_properties"}; - - if (isempty (has_features)) - try - gnuplot_version = __gnuplot_version__ (); - catch - ## Don't throw an error if gnuplot isn't installed - gnuplot_version = "0.0.0"; - end_try_catch - versions = {"4.2.5", "4.4", "4.4", "4.4", "4.2", "4.2", "4.4", "4.4", "4.4"}; - operators = {">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">="}; - have_features = logical (zeros (size (features))); - for n = 1 : numel (have_features) - has_features(n) = compare_versions (gnuplot_version, versions{n}, operators{n}); - endfor - endif - - n = find (strcmpi (feature, features)); - if (isempty (n)) - res = NaN; - else - res = has_features(n); - endif -endfunction -
--- a/scripts/plot/__gnuplot_open_stream__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,45 +0,0 @@ -## Copyright (C) 2009-2011 Ben Abbott -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {@var{stream} =} __gnuplot_open_stream__ (@var{npipes}, @var{h}) -## Undocumented internal function. -## @end deftypefn - -## Author: Ben Abbott <bpabbott@mac.com> -## Created: 2009-04-11 - -function plot_stream = __gnuplot_open_stream__ (npipes, h) - [prog, args] = gnuplot_binary (); - if (npipes > 1) - [plot_stream(1), plot_stream(2), pid] = popen2 (prog, args{:}); - if (pid < 0) - error ("__gnuplot_open_stream__: failed to open connection to gnuplot"); - else - plot_stream(3) = pid; - endif - else - plot_stream = popen (sprintf ("%s ", prog, args{:}), "w"); - if (plot_stream < 0) - error ("__gnuplot_open_stream__: failed to open connection to gnuplot"); - endif - endif - if (nargin > 1) - set (h, "__plot_stream__", plot_stream); - endif -endfunction
--- a/scripts/plot/__gnuplot_print__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,300 +0,0 @@ -## Copyright (C) 1999-2011 Daniel Heiserer -## Copyright (C) 2001 Laurent Mazet -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} __gnuplot_print__ (@var{@dots{}}) -## Undocumented internal function. -## @end deftypefn - -## Author: Daniel Heiserer <Daniel.heiserer@physik.tu-muenchen.de> -## Adapted-By: jwe - -function opts = __gnuplot_print__ (opts) - - dos_shell = (ispc () && ! isunix ()); - - if (isempty (opts.fontsize)) - ## If no fontsize, determine the nominal axes fontsize. - defaultfontsize = get (0, "defaultaxesfontsize"); - axesfontsize = get (findobj (opts.figure, "type", "axes"), "fontsize"); - if (iscell (axesfontsize)) - axesfontsize = round (median (cell2mat (axesfontsize))); - endif - if (isempty (axesfontsize)) - opts.fontsize = defaultfontsize; - else - opts.fontsize = axesfontsize; - endif - endif - ## The axes-label and tick-label spacing is determined by - ## the font spec given in "set terminal ..." - gp_opts = font_spec (opts); - - pipeline = ""; - - switch (lower (opts.devopt)) - case {"eps", "eps2", "epsc", "epsc2"} - if (any (strcmp (opts.devopt, {"eps", "epsc"}))) - gp_opts = sprintf ("%s level1", gp_opts); - endif - if (opts.tight_flag || ! isempty (opts.preview)) - tmp_file = strcat (tmpnam (), ".eps"); - eps_drawnow (opts, tmp_file, gp_opts); - if (dos_shell) - cleanup = sprintf (" & del %s", strrep (tmp_file, '/', '\')); - else - cleanup = sprintf (" ; rm %s", tmp_file); - endif - pipeline = {sprintf("%s %s", - opts.epstool_cmd (opts, tmp_file, opts.name), - cleanup)}; - else - eps_drawnow (opts, opts.name, gp_opts); - endif - case {"epslatex", "pslatex", "pstex", "epslatexstandalone"} - dot = find (opts.name == ".", 1, "last"); - if ((! isempty (dot)) - && any (strcmpi (opts.name(dot:end), - {".eps", ".ps", ".pdf", ".tex", "."}))) - name = opts.name(1:dot-1); - endif - if (strfind (opts.devopt, "standalone")) - term = sprintf ("%s ", - strrep (opts.devopt, "standalone", " standalone")); - else - term = sprintf ("%s ", opts.devopt); - endif - if (__gnuplot_has_feature__ ("epslatex_implies_eps_filesuffix")) - suffix = "tex"; - else - %% Gnuplot 4.0 wants a ".eps" suffix. - suffix = "eps"; - endif - local_drawnow (sprintf ("%s %s", term, gp_opts), - strcat (name, ".", suffix), opts); - case "tikz" - if (__gnuplot_has_terminal__ ("tikz")) - local_drawnow (sprintf ("lua tikz %s", gp_opts), opts.name, opts); - else - error (sprintf ("print:no%soutput", opts.devopt), - "print.m: '%s' output is not available for gnuplot-%s", - upper (opts.devopt), __gnuplot_version__ ()); - endif - case "svg" - local_drawnow (sprintf ("svg dynamic %s", gp_opts), opts.name, opts); - case {"aifm", "corel", "eepic", "emf", "fig"} - local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts); - case {"pdfcairo", "pngcairo"} - if (__gnuplot_has_terminal__ (opts.devopt)) - local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts); - else - error (sprintf ("print:no%soutput", opts.devopt), - "print.m: '%s' output is not available for gnuplot-%s", - upper (opts.devopt), __gnuplot_version__ ()); - endif - case {"canvas", "dxf", "hpgl", "mf", "gif", "pstricks", "texdraw"} - local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts); - case opts.ghostscript.device - gp_opts = font_spec (opts, "devopt", "eps"); - opts.ghostscript.output = opts.name; - opts.ghostscript.source = strcat (tmpnam (), ".eps"); - eps_drawnow (opts, opts.ghostscript.source, gp_opts); - [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript); - if (opts.send_to_printer || isempty (opts.name)) - cmd_lpr = opts.lpr_cmd (opts); - cmd = sprintf ("%s | %s", cmd_gs, cmd_lpr); - else - cmd = sprintf ("%s", cmd_gs); - endif - if (dos_shell) - cmd = sprintf ("%s & del %s", cmd, strrep (opts.ghostscript.source, '/', '\')); - else - cmd = sprintf ("%s ; rm %s", cmd, opts.ghostscript.source); - endif - if (! isempty (cmd_cleanup)) - if (dos_shell) - pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)}; - else - pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)}; - endif - else - pipeline = {cmd}; - endif - otherwise - error (sprintf ("print:no%soutput", opts.devopt), - "print.m: %s output is not available for the Gnuplot graphics toolkit", - upper (opts.devopt)); - endswitch - - - opts.pipeline = pipeline; - - for n = 1:numel(pipeline) - if (opts.debug) - fprintf ("gnuplot-pipeline: '%s'\n", pipeline{n}); - endif - [status, output] = system (pipeline{n}); - if (status) - fprintf ("%s\n%s\n%s\n", - "---------- output begin ----------", - output, - "----------- output end -----------"); - error ("gnuplot:failedpipe", "print: failed to print"); - endif - endfor - -endfunction - -function eps_drawnow (opts, epsfile, gp_opts) - [h, fontsize] = get_figure_text_objs (opts); - unwind_protect - for n = 1:numel(h) - set (h(n), "fontsize", 2 * fontsize{n}); - endfor - local_drawnow (sprintf ("postscript eps %s", gp_opts), epsfile, opts); - unwind_protect_cleanup - for n = 1:numel(h) - set (h(n), "fontsize", fontsize{n}); - endfor - end_unwind_protect -endfunction - -function local_drawnow (term, file, opts) - if (opts.use_color < 0) - mono = true; - else - mono = false; - endif - figure (opts.figure); - if (isempty (opts.debug_file) || ! opts.debug) - drawnow (term, file, mono); - else - drawnow (term, file, mono, opts.debug_file); - endif -endfunction - -function f = font_spec (opts, varargin) - for n = 1:2:numel(varargin) - opts.(varargin{n}) = varargin{n+1}; - endfor - f = ""; - switch (opts.devopt) - case "cgm" - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - f = sprintf ("font ""%s,%d""", opts.font, opts.fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("font ""%s""", opts.font); - elseif (! isempty (opts.fontsize)) - f = sprintf ("%d", opts.fontsize); - endif - case {"eps", "eps2", "epsc", "epsc2"} - ## Gnuplot renders fonts as half their specification, which - ## results in a tight spacing for the axes-labels and tick-labels. - ## Compensate for the half scale. This will produce the proper - ## spacing for the requested fontsize. - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - f = sprintf ("font ""%s,%d""", opts.font, 2 * opts.fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("font ""%s""", opts.font); - elseif (! isempty (opts.fontsize)) - f = sprintf ("%d", 2 * opts.fontsize); - endif - case "svg" - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - fontsize = round (opts.fontsize * 0.75); - f = sprintf ("fname ""%s"" fsize %d", opts.font, fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("fname ""%s""", opts.font); - elseif (! isempty (opts.fontsize)) - fontsize = round (opts.fontsize * 0.75); - f = sprintf ("%s fsize %d", f, fontsize); - endif - case "pdf" - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - f = sprintf ("font ""%s,%d""", opts.font, opts.fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("font ""%s""", opts.font); - elseif (! isempty (opts.fontsize)) - f = sprintf ("fsize %d", f, opts.fontsize); - endif - case {"pdfcairo", "pngcairo"} - if (! isempty (opts.font)) - f = sprintf ("font ""%s""", opts.font); - endif - case {"epslatex", "epslatexstandalone"} - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - f = sprintf ("font ""%s,%d""", opts.font, opts.fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("font ""%s""", opts.font); - elseif (! isempty (opts.fontsize)) - f = sprintf ("%d", opts.fontsize); - endif - case "pslatex" - if (! isempty (opts.fontsize)) - f = sprintf ("%d", opts.fontsize); - endif - case {"gif", "jpeg", "png"} - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - f = sprintf ("font ""%s ,%d""", opts.font, opts.fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("font ""%s""", opts.font); - elseif (! isempty (opts.fontsize)) - f = sprintf ("font ""%d""", opts.fontsize); - endif - case "emf" - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - f = sprintf ("""%s"" %d", opts.font, opts.fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("""%s""", opts.font); - elseif (! isempty (opts.fontsize)) - f = sprintf ("%d", opts.fontsize); - endif - case "canvas" - if (! isempty (opts.fontsize)) - f = sprintf ("fsize %d", opts.fontsize); - endif - case {"aifm", "corel"} - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - f = sprintf ("%s %d", opts.font, opts.fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("%s", opts.font); - elseif (! isempty (opts.fontsize)) - f = sprintf ("%d", opts.fontsize); - endif - case "fig" - if (! isempty (opts.font) && ! isempty (opts.fontsize)) - f = sprintf ("font %s fontsize %d", opts.font, opts.fontsize); - elseif (! isempty (opts.font)) - f = sprintf ("font %s", opts.font); - elseif (! isempty (opts.fontsize)) - f = sprintf ("fontsize %d", opts.fontsize); - endif - endswitch -endfunction - -function [h, fontsize] = get_figure_text_objs (opts) - h = findall (opts.figure, "-property", "fontsize"); - fontsize = get (h, "fontsize"); - switch (numel (fontsize)) - case 0 - fontsize = {}; - case 1 - fontsize = {fontsize}; - endswitch -endfunction
--- a/scripts/plot/__gnuplot_version__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -## Copyright (C) 2006-2011 Daniel Sebald -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {@var{version} =} __gnuplot_version__ () -## Undocumented internal function. -## @end deftypefn - -## Return the version of gnuplot we are using. Note that we do not -## attempt to handle the case of the user switching to different -## versions of gnuplot during the same session. - -function version = __gnuplot_version__ () - - persistent __version__ = ""; - - if (isempty (__version__)) - [status, output] = system (sprintf ("\"%s\" --version", gnuplot_binary ())); - if (status != 0) - ## This message ends in a newline so that the traceback messages - ## are skipped and people might actually see the message, read it, - ## comprehend it, actually take the advice it gives, and stop - ## asking us why plotting fails when gnuplot is not found. - error ("you must have gnuplot installed to display graphics; if you have gnuplot installed in a non-standard location, see the 'gnuplot_binary' function\n"); - endif - output = strrep (output, "gnuplot", ""); - output = strrep (output, "patchlevel", "."); - output = strrep (output, "\n", ""); - output = strrep (output, "\r", ""); - __version__ = strrep (output, " ", ""); - endif - - version = __version__; - -endfunction -
--- a/scripts/plot/__go_draw_axes__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,2456 +0,0 @@ -## Copyright (C) 2005-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} __go_draw_axes__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono}) -## Undocumented internal function. -## @end deftypefn - -## Author: jwe - -function __go_draw_axes__ (h, plot_stream, enhanced, mono, - bg_is_set, fg_is_set, hlgnd) - - if (nargin >= 4 && nargin <= 7) - - showhiddenhandles = get (0, "showhiddenhandles"); - unwind_protect - set (0, "showhiddenhandles", "on"); - axis_obj = __get__ (h); - unwind_protect_cleanup - set (0, "showhiddenhandles", showhiddenhandles); - end_unwind_protect - - parent_figure_obj = get (axis_obj.parent); - gnuplot_term = __gnuplot_get_var__ (axis_obj.parent, "GPVAL_TERM"); - - ## Set to false for plotyy axes. - if (strcmp (axis_obj.tag, "plotyy")) - ymirror = false; - else - ymirror = true; - endif - - nd = __calc_dimensions__ (h); - - if (strcmp (axis_obj.dataaspectratiomode, "manual") - && strcmp (axis_obj.xlimmode, "manual") - && strcmp (axis_obj.ylimmode, "manual")) - ## All can't be "manual" - axis_obj.plotboxaspectratiomode = "auto"; - endif - - if (strcmp (axis_obj.dataaspectratiomode, "manual") - && strcmp (axis_obj.xlimmode, "manual") - && strcmp (axis_obj.ylimmode, "manual") - && (nd == 2 || all (mod (axis_obj.view, 90) == 0))) - ## FIXME - adjust plotboxaspectratio to respect other - fpos = get (axis_obj.parent, "position"); - apos = axis_obj.position; - endif - - pos = __actual_axis_position__ (h); - - if (strcmpi (axis_obj.dataaspectratiomode, "manual")) - dr = axis_obj.dataaspectratio; - if (nd == 2 || all (mod (axis_obj.view, 90) == 0)) - dr = dr(1) / dr(2); - else - ## FIXME - need to properly implement 3D - dr = mean (dr(1:2)) / dr(3); - endif - else - dr = 1; - endif - - if (strcmp (axis_obj.activepositionproperty, "position")) - if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin")) - if (nd == 2 || all (mod (axis_obj.view, 90) == 0)) - x = [1, 1]; - else - ## 3D plots need to be sized down to fit in the window. - x = 1.0 ./ sqrt([2, 2.5]); - endif - fprintf (plot_stream, "set tmargin screen %.15g;\n", - pos(2)+pos(4)/2+x(2)*pos(4)/2); - fprintf (plot_stream, "set bmargin screen %.15g;\n", - pos(2)+pos(4)/2-x(2)*pos(4)/2); - fprintf (plot_stream, "set lmargin screen %.15g;\n", - pos(1)+pos(3)/2-x(1)*pos(3)/2); - fprintf (plot_stream, "set rmargin screen %.15g;\n", - pos(1)+pos(3)/2+x(1)*pos(3)/2); - sz_str = ""; - else - fprintf (plot_stream, "set tmargin 0;\n"); - fprintf (plot_stream, "set bmargin 0;\n"); - fprintf (plot_stream, "set lmargin 0;\n"); - fprintf (plot_stream, "set rmargin 0;\n"); - - if (nd == 3 && all (axis_obj.view == [0, 90])) - ## FIXME -- Kludge to allow colorbar to be added to a pcolor() plot - pos(3:4) = pos(3:4) * 1.4; - pos(1:2) = pos(1:2) - pos(3:4) * 0.125; - endif - - fprintf (plot_stream, "set origin %.15g, %.15g;\n", pos(1), pos(2)); - - if (strcmpi (axis_obj.dataaspectratiomode, "manual")) - sz_str = sprintf ("set size ratio %.15g", -dr); - else - sz_str = "set size noratio"; - endif - sz_str = sprintf ("%s %.15g, %.15g;\n", sz_str, pos(3), pos(4)); - endif - else ## activepositionproperty == outerposition - fprintf (plot_stream, "unset tmargin;\n"); - fprintf (plot_stream, "unset bmargin;\n"); - fprintf (plot_stream, "unset lmargin;\n"); - fprintf (plot_stream, "unset rmargin;\n"); - fprintf (plot_stream, "set origin %g, %g;\n", pos(1:2)); - sz_str = ""; - if (strcmpi (axis_obj.dataaspectratiomode, "manual")) - sz_str = sprintf ("ratio %g", -dr); - else - sz_str = "noratio"; - endif - sz_str = sprintf ("set size %s %g, %g;\n", sz_str, pos(3:4)); - endif - if (! isempty (sz_str)) - fputs (plot_stream, sz_str); - endif - - ## Reset all labels, axis-labels, tick-labels, and title - ## FIXME - We should have an function to initialize the axis. - ## Presently, this is dispersed in this function. - fputs (plot_stream, "unset label;\n"); - fputs (plot_stream, "unset xtics;\n"); - fputs (plot_stream, "unset ytics;\n"); - fputs (plot_stream, "unset ztics;\n"); - fputs (plot_stream, "unset x2tics;\n"); - fputs (plot_stream, "unset x2tics;\n"); - - if (! isempty (axis_obj.title)) - t = get (axis_obj.title); - if (isempty (t.string)) - fputs (plot_stream, "unset title;\n"); - else - [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); - fontspec = create_fontspec (f, s, gnuplot_term); - fprintf (plot_stream, "set title \"%s\" %s %s;\n", - undo_string_escapes (tt), fontspec, - __do_enhanced_option__ (enhanced, t)); - endif - endif - - if (! isempty (axis_obj.xlabel)) - t = get (axis_obj.xlabel); - angle = t.rotation; - colorspec = get_text_colorspec (axis_obj.xcolor, mono); - if (isempty (t.string)) - fprintf (plot_stream, "unset xlabel;\n"); - fprintf (plot_stream, "unset x2label;\n"); - else - [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); - fontspec = create_fontspec (f, s, gnuplot_term); - if (strcmpi (axis_obj.xaxislocation, "top")) - fprintf (plot_stream, "set x2label \"%s\" %s %s %s", - undo_string_escapes (tt), colorspec, fontspec, - __do_enhanced_option__ (enhanced, t)); - else - fprintf (plot_stream, "set xlabel \"%s\" %s %s %s", - undo_string_escapes (tt), colorspec, fontspec, - __do_enhanced_option__ (enhanced, t)); - endif - fprintf (plot_stream, " rotate by %f;\n", angle); - if (strcmpi (axis_obj.xaxislocation, "top")) - fprintf (plot_stream, "unset xlabel;\n"); - else - fprintf (plot_stream, "unset x2label;\n"); - endif - endif - endif - - if (! isempty (axis_obj.ylabel)) - t = get (axis_obj.ylabel); - angle = t.rotation; - colorspec = get_text_colorspec (axis_obj.ycolor, mono); - if (isempty (t.string)) - fprintf (plot_stream, "unset ylabel;\n"); - fprintf (plot_stream, "unset y2label;\n"); - else - [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); - fontspec = create_fontspec (f, s, gnuplot_term); - if (strcmpi (axis_obj.yaxislocation, "right")) - fprintf (plot_stream, "set y2label \"%s\" %s %s %s", - undo_string_escapes (tt), colorspec, fontspec, - __do_enhanced_option__ (enhanced, t)); - else - fprintf (plot_stream, "set ylabel \"%s\" %s %s %s", - undo_string_escapes (tt), colorspec, fontspec, - __do_enhanced_option__ (enhanced, t)); - endif - fprintf (plot_stream, " rotate by %f;\n", angle); - if (strcmpi (axis_obj.yaxislocation, "right")) - fprintf (plot_stream, "unset ylabel;\n"); - else - fprintf (plot_stream, "unset y2label;\n"); - endif - endif - endif - - if (! isempty (axis_obj.zlabel)) - t = get (axis_obj.zlabel); - angle = t.rotation; - colorspec = get_text_colorspec (axis_obj.zcolor, mono); - if (isempty (t.string)) - fputs (plot_stream, "unset zlabel;\n"); - else - [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); - fontspec = create_fontspec (f, s, gnuplot_term); - fprintf (plot_stream, "set zlabel \"%s\" %s %s %s", - undo_string_escapes (tt), colorspec, fontspec, - __do_enhanced_option__ (enhanced, t)); - fprintf (plot_stream, " rotate by %f;\n", angle); - endif - endif - - if (strcmpi (axis_obj.xaxislocation, "top")) - xaxisloc = "x2"; - xaxisloc_using = "x2"; - else - xaxisloc = "x"; - xaxisloc_using = "x1"; - if (strcmpi (axis_obj.xaxislocation, "zero")) - fputs (plot_stream, "set xzeroaxis;\n"); - endif - endif - if (strcmpi (axis_obj.yaxislocation, "right")) - yaxisloc = "y2"; - yaxisloc_using = "y2"; - else - yaxisloc = "y"; - yaxisloc_using = "y1"; - if (strcmpi (axis_obj.yaxislocation, "zero")) - fputs (plot_stream, "set yzeroaxis;\n"); - endif - endif - - have_grid = false; - - if (strcmpi (axis_obj.xgrid, "on")) - have_grid = true; - fprintf (plot_stream, "set grid %stics;\n", xaxisloc); - else - fprintf (plot_stream, "set grid no%stics;\n", xaxisloc); - endif - - if (strcmpi (axis_obj.ygrid, "on")) - have_grid = true; - fprintf (plot_stream, "set grid %stics;\n", yaxisloc); - else - fprintf (plot_stream, "set grid no%stics;\n", yaxisloc); - endif - - if (strcmpi (axis_obj.zgrid, "on")) - have_grid = true; - fputs (plot_stream, "set grid ztics;\n"); - else - fputs (plot_stream, "set grid noztics;\n"); - endif - - if (strcmpi (axis_obj.xminorgrid, "on")) - have_grid = true; - if (strcmp (axis_obj.xscale, "log")) - m = 10; - else - m = 5; - endif - fprintf (plot_stream, "set m%stics %d;\n", xaxisloc, m); - fprintf (plot_stream, "set grid m%stics;\n", xaxisloc); - else - fprintf (plot_stream, "set grid nom%stics;\n", xaxisloc); - endif - - if (strcmpi (axis_obj.yminorgrid, "on")) - have_grid = true; - if (strcmp (axis_obj.yscale, "log")) - m = 10; - else - m = 5; - endif - fprintf (plot_stream, "set m%stics %d;\n", yaxisloc, m); - fprintf (plot_stream, "set grid m%stics;\n", yaxisloc); - else - fprintf (plot_stream, "set grid nom%stics;\n", yaxisloc); - endif - - if (strcmpi (axis_obj.zminorgrid, "on")) - have_grid = true; - if (strcmp (axis_obj.zscale, "log")) - m = 10; - else - m = 5; - endif - fprintf (plot_stream, "set mztics %d;\n", m); - fputs (plot_stream, "set grid mztics;\n"); - else - fputs (plot_stream, "set grid nomztics;\n"); - endif - - ## The grid front/back/layerdefault option also controls the - ## appearance of tics, so it is used even if the grid is absent. - if (strcmpi (axis_obj.layer, "top")) - fputs (plot_stream, "set grid front;\n"); - fputs (plot_stream, "set border front;\n"); - else - fputs (plot_stream, "set grid layerdefault;\n"); - ## FIXME -- the gnuplot help says that "layerdefault" should work - ## for set border too, but it fails for me with gnuplot 4.2.5. So - ## use "back" instead. - fputs (plot_stream, "set border back;\n"); - endif - - fprintf (plot_stream, "set grid linewidth %f, linewidth %f;\n", - axis_obj.linewidth, axis_obj.linewidth); - - if (! have_grid) - fputs (plot_stream, "unset grid;\n"); - endif - - do_tics (axis_obj, plot_stream, ymirror, mono, gnuplot_term); - - fputs (plot_stream, "unset logscale;\n"); - xlogscale = strcmpi (axis_obj.xscale, "log"); - ylogscale = strcmpi (axis_obj.yscale, "log"); - zlogscale = strcmpi (axis_obj.zscale, "log"); - if (xlogscale) - fprintf (plot_stream, "set logscale %s;\n", xaxisloc); - endif - if (ylogscale) - fprintf (plot_stream, "set logscale %s;\n", yaxisloc); - endif - if (zlogscale) - fputs (plot_stream, "set logscale z;\n"); - endif - - xautoscale = strcmpi (axis_obj.xlimmode, "auto"); - yautoscale = strcmpi (axis_obj.ylimmode, "auto"); - zautoscale = strcmpi (axis_obj.zlimmode, "auto"); - cautoscale = strcmpi (axis_obj.climmode, "auto"); - cdatadirect = false; - truecolor = false; - - fputs (plot_stream, "set clip two;\n"); - - kids = axis_obj.children; - ## Remove the axis labels and title from the children, and - ## preserved the original order. - [jnk, k] = setdiff (kids, [axis_obj.xlabel; axis_obj.ylabel; ... - axis_obj.zlabel; axis_obj.title]); - kids = kids (sort (k)); - - if (nd == 3) - fputs (plot_stream, "set parametric;\n"); - fputs (plot_stream, "set style data lines;\n"); - fputs (plot_stream, "set surface;\n"); - fputs (plot_stream, "unset contour;\n"); - endif - - data_idx = 0; - data = cell (); - is_image_data = []; - hidden_removal = NaN; - view_map = false; - - xlim = axis_obj.xlim; - ylim = axis_obj.ylim; - zlim = axis_obj.zlim; - clim = axis_obj.clim; - - if (! cautoscale && clim(1) == clim(2)) - clim(2)++; - endif - addedcmap = []; - - ximg_data = {}; - ximg_data_idx = 0; - - while (! isempty (kids)) - - obj = get (kids(end)); - if (isfield (obj, "units")) - units = obj.units; - unwind_protect - set (kids(end), "units", "data"); - obj = get (kids(end)); - unwind_protect_cleanup - set (kids(end), "units", units); - end_unwind_protect - endif - kids = kids(1:(end-1)); - - if (strcmpi (obj.visible, "off")) - continue; - endif - - if (xlogscale && isfield (obj, "xdata")) - obj.xdata(obj.xdata<=0) = NaN; - endif - if (ylogscale && isfield (obj, "ydata")) - obj.ydata(obj.ydata<=0) = NaN; - endif - if (zlogscale && isfield (obj, "zdata")) - obj.zdata(obj.zdata<=0) = NaN; - endif - - ## Check for facecolor interpolation for surfaces. - doing_interp_color = ... - isfield (obj, "facecolor") && strncmp (obj.facecolor, "interp", 6); - - switch (obj.type) - case "image" - img_data = obj.cdata; - img_xdata = obj.xdata; - img_ydata = obj.ydata; - - if (ndims (img_data) == 3) - truecolor = true; - elseif (strcmpi (obj.cdatamapping, "direct")) - cdatadirect = true; - endif - data_idx++; - is_image_data(data_idx) = true; - parametric(data_idx) = false; - have_cdata(data_idx) = false; - have_3d_patch(data_idx) = false; - - if (img_xdata(2) < img_xdata(1)) - img_xdata = img_xdata(2:-1:1); - img_data = img_data(:,end:-1:1,:); - elseif (img_xdata(1) == img_xdata(2)) - img_xdata = img_xdata(1) + [0, size(img_data,2)-1]; - endif - if (img_ydata(2) < img_ydata(1)) - img_ydata = img_ydata(2:-1:1); - img_data = img_data(end:-1:1,:,:); - elseif (img_ydata(1) == img_ydata(2)) - img_ydata = img_ydata(1) + [0, size(img_data,1)-1]; - endif - - [y_dim, x_dim] = size (img_data(:,:,1)); - if (x_dim > 1) - dx = abs (img_xdata(2)-img_xdata(1))/(x_dim-1); - else - x_dim = 2; - img_data = [img_data, img_data]; - dx = abs (img_xdata(2)-img_xdata(1)); - endif - if (y_dim > 1) - dy = abs (img_ydata(2)-img_ydata(1))/(y_dim-1); - else - y_dim = 2; - img_data = [img_data; img_data]; - dy = abs (img_ydata(2)-img_ydata(1)); - endif - - x_origin = min (img_xdata); - y_origin = min (img_ydata); - - if (ndims (img_data) == 3) - data{data_idx} = permute (img_data, [3, 1, 2])(:); - format = "1:2:3"; - imagetype = "rgbimage"; - else - data{data_idx} = img_data(:); - format = "1"; - imagetype = "image"; - endif - - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = sprintf ("binary array=%dx%d scan=yx origin=(%.15g,%.15g) dx=%.15g dy=%.15g using %s", - x_dim, y_dim, x_origin, y_origin, dx, dy, format); - withclause{data_idx} = sprintf ("with %s;", imagetype); - - case "line" - if (strncmp (obj.linestyle, "none", 4) - && (! isfield (obj, "marker") - || (isfield (obj, "marker") - && strncmp (obj.marker, "none", 4)))) - continue; - endif - data_idx++; - is_image_data(data_idx) = false; - parametric(data_idx) = true; - have_cdata(data_idx) = false; - have_3d_patch(data_idx) = false; - if (isempty (obj.displayname)) - titlespec{data_idx} = "title \"\""; - else - tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname")); - titlespec{data_idx} = cstrcat ("title \"", tmp, "\""); - endif - usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata)); - errbars = ""; - if (nd == 3) - xdat = obj.xdata(:); - ydat = obj.ydata(:); - if (! isempty (obj.zdata)) - zdat = obj.zdata(:); - else - zdat = zeros (size (xdat)); - endif - data{data_idx} = [xdat, ydat, zdat]'; - usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", numel (xdat)); - ## fputs (plot_stream, "set parametric;\n"); - else - xdat = obj.xdata(:); - ydat = obj.ydata(:); - data{data_idx} = [xdat, ydat]'; - usingclause{data_idx} = sprintf ("record=%d using ($1):($2) axes %s%s", - rows(xdat), xaxisloc_using, yaxisloc_using); - endif - - style = do_linestyle_command (obj, obj.color, data_idx, mono, - plot_stream, errbars); - - withclause{data_idx} = sprintf ("with %s linestyle %d", - style{1}, data_idx); - - if (length (style) > 1) - data_idx++; - is_image_data(data_idx) = is_image_data(data_idx - 1); - parametric(data_idx) = parametric(data_idx - 1); - have_cdata(data_idx) = have_cdata(data_idx - 1); - have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = usingclause{data_idx - 1}; - data{data_idx} = data{data_idx - 1}; - withclause{data_idx} = sprintf ("with %s linestyle %d", - style{2}, data_idx); - endif - if (length (style) > 2) - data_idx++; - is_image_data(data_idx) = is_image_data(data_idx - 1); - parametric(data_idx) = parametric(data_idx - 1); - have_cdata(data_idx) = have_cdata(data_idx - 1); - have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = usingclause{data_idx - 1}; - data{data_idx} = data{data_idx - 1}; - withclause{data_idx} = sprintf ("with %s linestyle %d", - style{3}, data_idx); - endif - - case "patch" - cmap = parent_figure_obj.colormap; - [nr, nc] = size (obj.xdata); - - if (! isempty (obj.cdata)) - cdat = obj.cdata; - if (strcmpi (obj.cdatamapping, "direct")) - cdatadirect = true; - endif - else - cdat = []; - endif - - data_3d_idx = NaN; - for i = 1:nc - xcol = obj.xdata(:,i); - ycol = obj.ydata(:,i); - if (nd == 3) - if (! isempty (obj.zdata)) - zcol = obj.zdata(:,i); - else - zcol = zeros (size (xcol)); - endif - endif - - if (! isnan (xcol) && ! isnan (ycol)) - ## Is the patch closed or not - if (strncmp (obj.facecolor, "none", 4)) - hidden_removal = false; - else - - if (isnan (hidden_removal)) - hidden_removal = true; - endif - if (nd == 3) - if (numel (xcol) > 3) - error ("__go_draw_axes__: gnuplot (as of v4.2) only supports 3D filled triangular patches"); - else - if (isnan (data_3d_idx)) - data_idx++; - data_3d_idx = data_idx; - is_image_data(data_idx) = false; - parametric(data_idx) = false; - have_cdata(data_idx) = true; - have_3d_patch(data_idx) = true; - withclause{data_3d_idx} = sprintf ("with pm3d"); - usingclause{data_3d_idx} = "using 1:2:3:4"; - data{data_3d_idx} = []; - endif - local_idx = data_3d_idx; - ccdat = NaN; - endif - else - data_idx++; - local_idx = data_idx; - is_image_data(data_idx) = false; - parametric(data_idx) = false; - have_cdata(data_idx) = false; - have_3d_patch(data_idx) = false; - endif - - if (i > 1 || isempty (obj.displayname)) - titlespec{local_idx} = "title \"\""; - else - tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname")); - titlespec{local_idx} = cstrcat ("title \"", tmp, "\""); - endif - if (isfield (obj, "facecolor")) - if ((strncmp (obj.facecolor, "flat", 4) - || strncmp (obj.facecolor, "interp", 6)) - && isfield (obj, "cdata")) - if (ndims (obj.cdata) == 2 - && (size (obj.cdata, 2) == nc - && (size (obj.cdata, 1) == 1 - || size (obj.cdata, 1) == 3))) - ccol = cdat (:, i); - elseif (ndims (obj.cdata) == 2 - && (size (obj.cdata, 1) == nc - && (size (obj.cdata, 2) == 1 - || size (obj.cdata, 2) == 3))) - ccol = cdat (i, :); - elseif (ndims (obj.cdata) == 3) - ccol = permute (cdat (:, i, :), [1, 3, 2]); - else - ccol = cdat; - endif - if (strncmp (obj.facecolor, "flat", 4)) - if (numel(ccol) == 3) - color = ccol; - elseif (nd == 3 && numel (xcol) == 3) - ccdat = ccol * ones (3,1); - else - r = 1 + round ((size (cmap, 1) - 1) - * (ccol - clim(1))/(clim(2) - clim(1))); - r = max (1, min (r, size (cmap, 1))); - color = cmap(r, :); - endif - elseif (strncmp (obj.facecolor, "interp", 6)) - if (nd == 3 && numel (xcol) == 3) - ccdat = ccol; - if (! isvector (ccdat)) - tmp = rows(cmap) + rows(addedcmap) + ... - [1 : rows(ccdat)]; - addedcmap = [addedcmap; ccdat]; - ccdat = tmp(:); - else - ccdat = ccdat(:); - endif - else - warning ("\"interp\" not supported, using 1st entry of cdata"); - r = 1 + round ((size (cmap, 1) - 1) * ccol(1)); - r = max (1, min (r, size (cmap, 1))); - color = cmap(r,:); - endif - endif - elseif (isnumeric (obj.facecolor)) - color = obj.facecolor; - else - color = [0, 1, 0]; - endif - else - color = [0, 1, 0]; - endif - - if (nd == 3 && numel (xcol) == 3) - if (isnan (ccdat)) - ccdat = (rows (cmap) + rows(addedcmap) + 1) * ones(3, 1); - addedcmap = [addedcmap; reshape(color, 1, 3)]; - endif - data{data_3d_idx} = [data{data_3d_idx}, ... - [[xcol; xcol(end)], [ycol; ycol(end)], ... - [zcol; zcol(end)], [ccdat; ccdat(end)]]']; - else - if (mono) - colorspec = ""; - elseif (__gnuplot_has_feature__ ("transparent_patches") - && isscalar (obj.facealpha)) - colorspec = sprintf ("lc rgb \"#%02x%02x%02x\" fillstyle transparent solid %f", - round (255*color), obj.facealpha); - else - colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", - round (255*color)); - endif - - withclause{data_idx} = sprintf ("with filledcurve %s", - colorspec); - data{data_idx} = [xcol, ycol]'; - usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", - numel (xcol)); - endif - endif - endif - - ## patch outline - if (!(strncmp (obj.edgecolor, "none", 4) - && (strncmp (obj.marker, "none", 4) - || (strncmp (obj.markeredgecolor, "none", 4) - && strncmp (obj.markerfacecolor, "none", 4))))) - - data_idx++; - is_image_data(data_idx) = false; - parametric(data_idx) = false; - have_cdata(data_idx) = false; - have_3d_patch(data_idx) = false; - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata)); - - if (isfield (obj, "markersize")) - mdat = obj.markersize / 3; - endif - - if (isfield (obj, "edgecolor")) - ## FIXME - ## This is the wrong thing to do as edgecolor, markeredgecolor - ## and markerfacecolor can have different values and we should - ## treat them seperately. However, the below allow the scatter - ## functions to work as expected, where only one of these values - ## is set - if (strncmp (obj.edgecolor, "none", 4)) - if (strncmp (obj.markeredgecolor, "none", 4)) - ec = obj.markerfacecolor; - else - ec = obj.markeredgecolor; - endif - else - ec = obj.edgecolor; - endif - - if ((strncmp (ec, "flat", 4) - || strncmp (ec, "interp", 6)) - && isfield (obj, "cdata")) - if (ndims (obj.cdata) == 2 - && (size (obj.cdata, 2) == nc - && (size (obj.cdata, 1) == 1 - || size (obj.cdata, 1) == 3))) - ccol = cdat (:, i); - elseif (ndims (obj.cdata) == 2 - && (size (obj.cdata, 1) == nc - && (size (obj.cdata, 2) == 1 - || size (obj.cdata, 2) == 3))) - ccol = cdat (i, :); - elseif (ndims (obj.cdata) == 3) - ccol = permute (cdat (:, i, :), [1, 3, 2]); - else - ccol = cdat; - endif - if (strncmp (ec, "flat", 4)) - if (numel(ccol) == 3) - color = ccol; - else - if (isscalar (ccol)) - ccol = repmat(ccol, numel (xcol), 1); - endif - color = "flat"; - have_cdata(data_idx) = true; - endif - elseif (strncmp (ec, "interp", 6)) - if (numel(ccol) == 3) - warning ("\"interp\" not supported, using 1st entry of cdata"); - color = ccol(1,:); - else - if (isscalar (ccol)) - ccol = repmat(ccol, numel (xcol), 1); - endif - color = "interp"; - have_cdata(data_idx) = true; - endif - endif - elseif (isnumeric (ec)) - color = ec; - else - color = [0, 0, 0]; - endif - else - color = [0, 0, 0]; - endif - - if (isfield (obj, "linestyle")) - switch (obj.linestyle) - case "-" - lt = "lt 1"; - case "--" - lt = "lt 2"; - case ":" - lt = "lt 3"; - case "-." - lt = "lt 6"; - case "none" - lt = ""; - otherwise - lt = ""; - endswitch - else - lt = ""; - endif - - if (isfield (obj, "linewidth")) - lw = sprintf("linewidth %f", obj.linewidth); - else - lw = ""; - endif - - [pt, pt2, obj] = gnuplot_pointtype (obj); - if (! isempty (pt)) - pt = sprintf ("pointtype %s", pt); - endif - if (! isempty (pt2)) - pt2 = sprintf ("pointtype %s", pt2); - endif - - if (mono) - colorspec = ""; - else - if (ischar (color)) - colorspec = "palette"; - else - colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", - round (255*color)); - endif - endif - - sidx = 1; - if (isempty (lt)) - style = ""; - else - style = "lines"; - endif - tmpwith = {}; - - facesame = true; - if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor") - && !strncmp (obj.markerfacecolor, "none", 4)) - if (strncmp (obj.markerfacecolor, "auto", 4) - || ! isnumeric (obj.markerfacecolor) - || (isnumeric (obj.markerfacecolor) - && isequal (color, obj.markerfacecolor))) - style = strcat (style, "points"); - if (isfield (obj, "markersize")) - if (length (mdat) == nc) - m = mdat(i); - else - m = mdat; - endif - ps = sprintf("pointsize %f", m / 3); - else - ps = ""; - endif - - tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", - style, lw, pt2, lt, ps, - colorspec); - else - facesame = false; - if (! isempty (style)) - tmpwith{sidx} = sprintf ("with %s %s %s %s", - style, lw, lt, - colorspec); - sidx ++; - endif - if (isnumeric (obj.markerfacecolor) && ! mono) - colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", - round (255*obj.markerfacecolor)); - endif - style = "points"; - if (isfield (obj, "markersize")) - if (length (mdat) == nc) - m = mdat(i); - else - m = mdat; - endif - ps = sprintf("pointsize %f", m / 3); - else - ps = ""; - endif - tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", - style, lw, pt2, lt, ps, - colorspec); - endif - endif - - if (isfield (obj, "markeredgecolor") - && !strncmp (obj.markeredgecolor, "none", 4)) - if (facesame && !isempty (pt) - && (strncmp (obj.markeredgecolor, "auto", 4) - || ! isnumeric (obj.markeredgecolor) - || (isnumeric (obj.markeredgecolor) - && isequal (color, obj.markeredgecolor)))) - if (sidx == 1 && ((length (style) == 5 - && strncmp (style, "lines", 5)) - || isempty (style))) - style = strcat (style, "points"); - if (isfield (obj, "markersize")) - if (length (mdat) == nc) - m = mdat(i); - else - m = mdat; - endif - ps = sprintf("pointsize %f", m / 3); - else - ps = ""; - endif - tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", - style, lw, pt, lt, ps, - colorspec); - endif - else - if (!isempty (style)) - if (length(tmpwith) < sidx || isempty (tmpwith{sidx})) - tmpwith{sidx} = sprintf ("with %s %s %s %s", - style, lw, lt, - colorspec); - endif - sidx ++; - endif - - if (!isempty (pt)) - if (! mono) - if (strncmp (obj.markeredgecolor, "auto", 4)) - colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", - round (255*color)); - elseif (isnumeric (obj.markeredgecolor) && ! mono) - colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", - round (255*obj.markeredgecolor)); - endif - endif - style = "points"; - if (isfield (obj, "markersize")) - if (length (mdat) == nc) - m = mdat(i); - else - m = mdat; - endif - ps = sprintf("pointsize %f", m / 3); - else - ps = ""; - endif - tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", - style, lw, pt, lt, ps, - colorspec); - endif - endif - endif - - if (isempty (tmpwith)) - withclause{data_idx} = sprintf ("with %s %s %s %s %s", - style, lw, pt, lt, - colorspec); - else - withclause{data_idx} = tmpwith{1}; - endif - if (nd == 3) - if (ischar (color)) - if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol)) - data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... - [zcol; zcol(1)], [ccol; ccol(1)]]'; - else - data{data_idx} = [xcol, ycol, zcol, ccol]'; - endif - usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4)", columns (data{data_idx})); - else - if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol)) - data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... - [zcol; zcol(1)]]'; - else - data{data_idx} = [xcol, ycol, zcol]'; - endif - usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx})); - endif - else - if (ischar (color)) - if (! isnan (xcol) && ! isnan (ycol)) - data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... - [ccol; ccol(1)]]'; - else - data{data_idx} = [xcol, ycol, ccol]'; - endif - usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx})); - else - if (! isnan (xcol) && ! isnan (ycol)) - data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]'; - else - data{data_idx} = [xcol, ycol]'; - endif - usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", columns (data{data_idx})); - endif - endif - - if (length (tmpwith) > 1) - data_idx++; - is_image_data(data_idx) = is_image_data(data_idx - 1); - parametric(data_idx) = parametric(data_idx - 1); - have_cdata(data_idx) = have_cdata(data_idx - 1); - have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = usingclause{data_idx - 1}; - data{data_idx} = data{data_idx - 1}; - withclause{data_idx} = tmpwith{2}; - endif - if (length (tmpwith) > 2) - data_idx++; - is_image_data(data_idx) = is_image_data(data_idx - 1); - parametric(data_idx) = parametric(data_idx - 1); - have_cdata(data_idx) = have_cdata(data_idx - 1); - have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = usingclause{data_idx - 1}; - data{data_idx} = data{data_idx - 1}; - withclause{data_idx} = tmpwith{3}; - endif - endif - endfor - - case "surface" - view_map = true; - if (! (strncmp (obj.edgecolor, "none", 4) - && strncmp (obj.facecolor, "none", 4))) - data_idx++; - is_image_data(data_idx) = false; - parametric(data_idx) = false; - have_cdata(data_idx) = true; - have_3d_patch(data_idx) = false; - style = do_linestyle_command (obj, obj.edgecolor, - data_idx, mono, - plot_stream); - - if (isempty (obj.displayname)) - titlespec{data_idx} = "title \"\""; - else - tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname")); - titlespec{data_idx} = cstrcat ("title \"", tmp, "\""); - endif - withclause{data_idx} = sprintf ("with pm3d linestyle %d", - data_idx); - withpm3d = true; - pm3didx = data_idx; - - xdat = obj.xdata; - ydat = obj.ydata; - zdat = obj.zdata; - cdat = obj.cdata; - - err = false; - if (! size_equal(zdat, cdat)) - err = true; - endif - if (isvector (xdat) && isvector (ydat) && ismatrix (zdat)) - if (rows (zdat) == length (ydat) - && columns (zdat) == length (xdat)) - [xdat, ydat] = meshgrid (xdat, ydat); - else - err = true; - endif - elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat)) - if (! size_equal (xdat, ydat, zdat)) - err = true; - endif - else - err = true; - endif - if (err) - error ("__go_draw_axes__: invalid grid data"); - endif - xlen = columns (zdat); - ylen = rows (zdat); - if (xlen == columns (xdat) && xlen == columns (ydat) - && ylen == rows (xdat) && ylen == rows (ydat)) - len = 4 * xlen; - zz = zeros (ylen, len); - k = 1; - for kk = 1:4:len - zz(:,kk) = xdat(:,k); - zz(:,kk+1) = ydat(:,k); - zz(:,kk+2) = zdat(:,k); - zz(:,kk+3) = cdat(:,k); - k++; - endfor - data{data_idx} = zz.'; - endif - - if (doing_interp_color) - interp_str = "interpolate 0, 0"; - else - ## No interpolation of facecolors. - interp_str = ""; - endif - usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3):($4)", ylen, xlen); - - flat_interp_face = (strncmp (obj.facecolor, "flat", 4) - || strncmp (obj.facecolor, "interp", 6)); - flat_interp_edge = (strncmp (obj.edgecolor, "flat", 4) - || strncmp (obj.edgecolor, "interp", 6)); - - facecolor_none_or_white = (strncmp (obj.facecolor, "none", 4) - || (isnumeric (obj.facecolor) - && all (obj.facecolor == 1))); - hidden_removal = false; - fputs (plot_stream, "set style increment default;\n"); - if (flat_interp_edge && facecolor_none_or_white) - withpm3d = false; - withclause{data_idx} = sprintf ("with %s palette", style {1}); - fputs (plot_stream, "unset pm3d\n"); - if (all (obj.facecolor == 1)) - hidden_removal = true; - endif - elseif (facecolor_none_or_white) - if (all (obj.facecolor == 1)) - hidden_removal = true; - endif - fputs(plot_stream,"unset pm3d;\n"); - fputs(plot_stream,"set style increment user;\n"); - withpm3d = false; - withclause{data_idx} = sprintf("with %s linestyle %d", - style{1}, data_idx); - fputs (plot_stream, "unset pm3d\n"); - endif - - if (doing_interp_color) - ## "depthorder" interferes with interpolation of colors. - dord = "scansautomatic"; - else - dord = "depthorder"; - endif - - if (flat_interp_face && strncmp (obj.edgecolor, "flat", 4)) - fprintf (plot_stream, "set pm3d explicit at s %s %s corners2color c3;\n", - interp_str, dord); - elseif (!facecolor_none_or_white) - if (strncmp (obj.edgecolor, "none", 4)) - if (__gnuplot_has_feature__ ("transparent_surface") - && isscalar (obj.facealpha)) - fprintf (plot_stream, - "set style fill transparent solid %f;\n", - obj.facealpha); - endif - fprintf (plot_stream, "set pm3d explicit at s %s corners2color c3;\n", - interp_str, dord); - else - fprintf (plot_stream, "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n", - data_idx, interp_str, dord); - - if (__gnuplot_has_feature__ ("transparent_surface") - && isscalar (obj.facealpha)) - fprintf (plot_stream, - "set style fill transparent solid %f;\n", - obj.facealpha); - endif - endif - endif - - zz = []; - if (length (style) > 1) - len = 3 * xlen; - zz = zeros (ylen, len); - k = 1; - for kk = 1:3:len - zz(:,kk) = xdat(:,k); - zz(:,kk+1) = ydat(:,k); - zz(:,kk+2) = zdat(:,k); - k++; - endfor - zz = zz.'; - - data_idx++; - is_image_data(data_idx) = is_image_data(data_idx - 1); - parametric(data_idx) = parametric(data_idx - 1); - have_cdata(data_idx) = false; - have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen); - data{data_idx} = zz; - withclause{data_idx} = sprintf ("with %s linestyle %d", - style{2}, data_idx); - - endif - if (length (style) > 2) - data_idx++; - is_image_data(data_idx) = is_image_data(data_idx - 1); - parametric(data_idx) = parametric(data_idx - 1); - have_cdata(data_idx) = false; - have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen); - data{data_idx} = zz; - withclause{data_idx} = sprintf ("with %s linestyle %d", - style{3}, data_idx); - endif - if (withpm3d && strncmp (style {1}, "linespoints", 11)) - if (isempty(zz)) - len = 3 * xlen; - zz = zeros (ylen, len); - k = 1; - for kk = 1:3:len - zz(:,kk) = xdat(:,k); - zz(:,kk+1) = ydat(:,k); - zz(:,kk+2) = zdat(:,k); - k++; - endfor - zz = zz.'; - endif - data_idx++; - is_image_data(data_idx) = is_image_data(data_idx - 1); - parametric(data_idx) = parametric(data_idx - 1); - have_cdata(data_idx) = false; - have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); - titlespec{data_idx} = "title \"\""; - usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen); - data{data_idx} = zz; - withclause{data_idx} = sprintf ("with points linestyle %d", - pm3didx); - endif - endif - - case "text" - [label, f, s] = __maybe_munge_text__ (enhanced, obj, "string"); - fontspec = create_fontspec (f, s, gnuplot_term); - lpos = obj.position; - halign = obj.horizontalalignment; - valign = obj.verticalalignment; - angle = obj.rotation; - units = obj.units; - color = obj.color; - if (strcmpi (units, "normalized")) - units = "graph"; - elseif (strcmp (axis_obj.yaxislocation, "right") - && strcmp (units, "data")) - units = "second"; - else - units = ""; - endif - - if (isnumeric (color)) - colorspec = get_text_colorspec (color, mono); - endif - - switch valign - ## Text offset in characters. This relies on gnuplot for font metrics. - case "top" - dy = -0.5; - case "cap" - dy = -0.5; - case "middle" - dy = 0; - case "baseline" - dy = 0.5; - case "bottom" - dy = 0.5; - endswitch - ## Gnuplot's Character units are different for x/y and vary with fontsize. The aspect ratio - ## of 1:1.7 was determined by experiment to work for eps/ps/etc. For the MacOS aqua terminal - ## a value of 2.5 is needed. However, the difference is barely noticable. - dx_and_dy = [(-dy * sind (angle)), (dy * cosd(angle))] .* [1.7 1]; - - if (nd == 3) - ## This produces the desired vertical alignment in 3D. - fprintf (plot_stream, - "set label \"%s\" at %s %.15e,%.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n", - undo_string_escapes (label), units, lpos(1), - lpos(2), lpos(3), halign, angle, dx_and_dy, fontspec, - __do_enhanced_option__ (enhanced, obj), colorspec); - else - fprintf (plot_stream, - "set label \"%s\" at %s %.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n", - undo_string_escapes (label), units, - lpos(1), lpos(2), halign, angle, dx_and_dy, fontspec, - __do_enhanced_option__ (enhanced, obj), colorspec); - endif - - case "hggroup" - ## Push group children into the kid list. - if (isempty (kids)) - kids = obj.children; - elseif (! isempty (obj.children)) - kids = [kids; obj.children]; - endif - - otherwise - error ("__go_draw_axes__: unknown object class, %s", - obj.type); - endswitch - - endwhile - - ## This is need to prevent warnings for rotations in 3D plots, while - ## allowing colorbars with contours. - if (nd == 2 || (data_idx > 1 && !view_map)) - fputs (plot_stream, "set pm3d implicit;\n"); - else - fputs (plot_stream, "set pm3d explicit;\n"); - endif - - if (isnan(hidden_removal) || hidden_removal) - fputs (plot_stream, "set hidden3d;\n"); - else - fputs (plot_stream, "unset hidden3d;\n"); - endif - - have_data = (! (isempty (data) || all (cellfun (@isempty, data)))); - - ## Note we don't use the [xy]2range of gnuplot as we don't use the - ## dual axis plotting features of gnuplot. - if (isempty (xlim)) - return; - endif - if (strcmpi (axis_obj.xdir, "reverse")) - xdir = "reverse"; - else - xdir = "noreverse"; - endif - fprintf (plot_stream, "set xrange [%.15e:%.15e] %s;\n", xlim, xdir); - if (strcmpi (axis_obj.xaxislocation, "top")) - fprintf (plot_stream, "set x2range [%.15e:%.15e] %s;\n", xlim, xdir); - endif - - if (isempty (ylim)) - return; - endif - if (strcmpi (axis_obj.ydir, "reverse")) - ydir = "reverse"; - else - ydir = "noreverse"; - endif - fprintf (plot_stream, "set yrange [%.15e:%.15e] %s;\n", ylim, ydir); - if (strcmpi (axis_obj.yaxislocation, "right")) - fprintf (plot_stream, "set y2range [%.15e:%.15e] %s;\n", ylim, ydir); - endif - - if (nd == 3) - if (isempty (zlim)) - return; - endif - if (strcmpi (axis_obj.zdir, "reverse")) - zdir = "reverse"; - else - zdir = "noreverse"; - endif - fprintf (plot_stream, "set zrange [%.15e:%.15e] %s;\n", zlim, zdir); - endif - - cmap = parent_figure_obj.colormap; - cmap_sz = rows(cmap); - if (! any (isinf (clim))) - if (truecolor || ! cdatadirect) - if (rows(addedcmap) > 0) - for i = 1:data_idx - if (have_3d_patch(i)) - data{i}(end,:) = clim(2) * (data{i}(end, :) - 0.5) / cmap_sz; - endif - endfor - fprintf (plot_stream, "set cbrange [%g:%g];\n", clim(1), clim(2) * - (cmap_sz + rows(addedcmap)) / cmap_sz); - else - fprintf (plot_stream, "set cbrange [%g:%g];\n", clim); - endif - else - fprintf (plot_stream, "set cbrange [1:%d];\n", cmap_sz + - rows (addedcmap)); - endif - endif - - if (strcmpi (axis_obj.box, "on")) - if (nd == 3) - fputs (plot_stream, "set border 4095;\n"); - else - fputs (plot_stream, "set border 431;\n"); - endif - else - if (nd == 3) - fputs (plot_stream, "set border 895;\n"); - elseif (! isempty (axis_obj.ytick)) - if (strcmpi (axis_obj.yaxislocation, "right")) - fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n", - axis_obj.tickdir); - if (strcmpi (axis_obj.xaxislocation, "top")) - fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n", - axis_obj.tickdir); - fputs (plot_stream, "set border 12;\n"); - else - fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n", - axis_obj.tickdir); - fputs (plot_stream, "set border 9;\n"); - endif - else - fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n", - axis_obj.tickdir); - if (strcmpi (axis_obj.xaxislocation, "top")) - fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n", - axis_obj.tickdir); - fputs (plot_stream, "set border 6;\n"); - else - fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n", - axis_obj.tickdir); - fputs (plot_stream, "set border 3;\n"); - endif - endif - endif - endif - - if (strcmpi (axis_obj.visible, "off")) - fputs (plot_stream, "unset border; unset tics\n"); - else - fprintf (plot_stream, "set border lw %f;\n", axis_obj.linewidth); - endif - - if (! isempty (hlgnd) && ! isempty (hlgnd.children) - && any (strcmpi (get (hlgnd.children, "visible"), "on"))) - if (strcmpi (hlgnd.box, "on")) - box = "box"; - else - box = "nobox"; - endif - if (strcmpi (hlgnd.orientation, "vertical")) - horzvert = "vertical"; - else - horzvert = "horizontal"; - endif - if (strcmpi (hlgnd.textposition, "right")) - reverse = "reverse"; - else - reverse = "noreverse"; - endif - inout = "inside"; - keypos = hlgnd.location; - if (ischar (keypos)) - keypos = lower (keypos); - keyout = findstr (keypos, "outside"); - if (! isempty (keyout)) - inout = "outside"; - keypos = keypos(1:keyout-1); - endif - endif - switch (keypos) - case "north" - pos = "center top"; - case "south" - pos = "center bottom"; - case "east" - pos = "right center"; - case "west" - pos = "left center"; - case "northeast" - pos = "right top"; - case "northwest" - pos = "left top"; - case "southeast" - pos = "right bottom"; - case "southwest" - pos = "left bottom"; - case "best" - pos = ""; - warning ("legend: 'Best' not yet implemented for location specifier.\n"); - ## Least conflict with data in plot. - ## Least unused space outside plot. - otherwise - pos = ""; - endswitch - if (__gnuplot_has_feature__ ("key_has_font_properties")) - [fontname, fontsize] = get_fontname_and_size (hlgnd); - fontspec = create_fontspec (fontname, fontsize, gnuplot_term); - else - fontspec = ""; - endif - fprintf (plot_stream, "set key %s %s;\nset key %s %s %s %s;\n", - inout, pos, box, reverse, horzvert, fontspec); - else - fputs (plot_stream, "unset key;\n"); - endif - fputs (plot_stream, "set style data lines;\n"); - - cmap = [cmap; addedcmap]; - cmap_sz = cmap_sz + rows(addedcmap); - if (length(cmap) > 0) - fprintf (plot_stream, - "set palette positive color model RGB maxcolors %i;\n", - cmap_sz); - fprintf (plot_stream, - "set palette file \"-\" binary record=%d using 1:2:3:4;\n", - cmap_sz); - fwrite (plot_stream, [1:cmap_sz; cmap.'], "float32"); - fwrite (plot_stream, "\n"); - endif - - fputs (plot_stream, "unset colorbox;\n"); - - if (have_data) - if (nd == 2) - plot_cmd = "plot"; - else - plot_cmd = "splot"; - rot_x = 90 - axis_obj.view(2); - rot_z = axis_obj.view(1); - while (rot_z < 0) - rot_z += 360; - endwhile - fputs (plot_stream, "set ticslevel 0;\n"); - if (view_map && rot_x == 0 && rot_z == 0) - fputs (plot_stream, "set view map;\n"); - else - fprintf (plot_stream, "set view %.15g, %.15g;\n", rot_x, rot_z); - endif - endif - if (have_3d_patch (1)) - fputs (plot_stream, "set pm3d depthorder\n"); - fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, - usingclause{1}, titlespec{1}, withclause{1}); - elseif (is_image_data (1)) - fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, - usingclause{1}, titlespec{1}, withclause{1}); - else - fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd, - usingclause{1}, titlespec{1}, withclause{1}); - endif - for i = 2:data_idx - if (have_3d_patch (i)) - fprintf (plot_stream, ", \"-\" %s %s %s \\\n", - usingclause{i}, titlespec{i}, withclause{i}); - elseif (is_image_data (i)) - if (! is_image_data (i-1)) - fputs (plot_stream, "; "); - if (bg_is_set) - fputs (plot_stream, "unset obj 1; \\\n"); - bg_is_set = false; - endif - if (fg_is_set) - fputs (plot_stream, "unset obj 2; \\\n"); - fg_is_set = false; - endif - endif - fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, - usingclause{i}, titlespec{i}, withclause{i}); - elseif (is_image_data (i-1)) - if (bg_is_set) - fputs (plot_stream, "unset obj 1; \\\n"); - bg_is_set = false; - endif - if (fg_is_set) - fputs (plot_stream, "unset obj 2; \\\n"); - fg_is_set = false; - endif - fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd, - usingclause{i}, titlespec{i}, withclause{i}); - else - fprintf (plot_stream, ", \"-\" binary format='%%float64' %s %s %s \\\n", - usingclause{i}, titlespec{i}, withclause{i}); - endif - endfor - fputs (plot_stream, ";\n"); - for i = 1:data_idx - if (have_3d_patch (i)) - ## Can't write 3d patch data as binary as can't plot more than - ## a single patch at a time and have to plot all patches together - ## so that the gnuplot depth ordering is done correctly - for j = 1 : 4 : columns(data{i}) - if (j != 1) - fputs (plot_stream, "\n\n"); - endif - fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j).'); - fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n", data{i}(:,j+1).'); - fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+2).'); - fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+3).'); - endfor - fputs (plot_stream, "e\n"); - elseif (is_image_data(i)) - fwrite (plot_stream, data{i}, "float32"); - else - __gnuplot_write_data__ (plot_stream, data{i}, nd, parametric(i), - have_cdata(i)); - endif - endfor - else - fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n"); - endif - - ## Needed to allow mouse rotation with pcolor. - if (view_map) - fputs (plot_stream, "unset view;\n"); - endif - - if (bg_is_set) - fputs (plot_stream, "unset obj 1;\n"); - bg_is_set = false; - endif - - fflush (plot_stream); - - else - print_usage (); - endif - -endfunction - -function fontspec = create_fontspec (f, s, gp_term) - if (strcmp (f, "*") || strcmp (gp_term, "tikz")) - fontspec = sprintf ("font \",%d\"", s); - else - fontspec = sprintf ("font \"%s,%d\"", f, s); - endif -endfunction - -function style = do_linestyle_command (obj, linecolor, idx, mono, - plot_stream, errbars = "") - style = {}; - - fprintf (plot_stream, "set style line %d default;\n", idx); - fprintf (plot_stream, "set style line %d", idx); - - found_style = false; - if (isnumeric (linecolor)) - color = linecolor; - if (! mono) - fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", - round (255*color)); - endif - else - color = [0, 0, 0]; - endif - - if (isfield (obj, "linestyle")) - switch (obj.linestyle) - case "-" - lt = "1"; - case "--" - lt = "2"; - case ":" - lt = "3"; - case "-." - lt = "6"; - case "none" - lt = ""; - otherwise - lt = ""; - endswitch - - if (! isempty (lt)) - fprintf (plot_stream, " linetype %s", lt); - endif - - else - lt = ""; - endif - if (! isempty (errbars)) - found_style = true; - endif - - if (isfield (obj, "linewidth")) - fprintf (plot_stream, " linewidth %f", obj.linewidth); - found_style = true; - endif - - [pt, pt2, obj] = gnuplot_pointtype (obj); - - if (! isempty (pt)) - found_style = true; - endif - - sidx = 1; - if (isempty (errbars)) - if (isempty (lt)) - style {sidx} = ""; - else - style {sidx} = "lines"; - endif - - facesame = true; - if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor") - && !strncmp (obj.markerfacecolor, "none", 4)) - if (strncmp (obj.markerfacecolor, "auto", 4) - || ! isnumeric (obj.markerfacecolor) - || (isnumeric (obj.markerfacecolor) - && isequal (color, obj.markerfacecolor))) - if (! isempty (pt2)) - fprintf (plot_stream, " pointtype %s", pt2); - style {sidx} = strcat (style{sidx}, "points"); - endif - if (isfield (obj, "markersize")) - fprintf (plot_stream, " pointsize %f", obj.markersize / 3); - endif - else - facesame = false; - if (! found_style) - fputs (plot_stream, " default"); - endif - fputs (plot_stream, ";\n"); - if (! isempty (style {sidx})) - sidx ++; - idx ++; - else - fputs (plot_stream, ";\n"); - endif - fprintf (plot_stream, "set style line %d default;\n", idx); - fprintf (plot_stream, "set style line %d", idx); - if (isnumeric (obj.markerfacecolor) && ! mono) - fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", - round (255*obj.markerfacecolor)); - endif - if (! isempty (pt2)) - style {sidx} = "points"; - fprintf (plot_stream, " pointtype %s", pt2); - endif - if (isfield (obj, "markersize")) - fprintf (plot_stream, " pointsize %f", obj.markersize / 3); - endif - endif - endif - if (isfield (obj, "markeredgecolor") - && !strncmp (obj.markeredgecolor, "none", 4)) - if (facesame && !isempty (pt) - && (strncmp (obj.markeredgecolor, "auto", 4) - || ! isnumeric (obj.markeredgecolor) - || (isnumeric (obj.markeredgecolor) - && isequal (color, obj.markeredgecolor)))) - if (sidx == 1 && ((length (style {sidx}) == 5 - && strncmp (style {sidx}, "lines", 5)) || isempty (style {sidx}))) - if (! isempty (pt)) - style {sidx} = strcat (style{sidx}, "points"); - fprintf (plot_stream, " pointtype %s", pt); - endif - if (isfield (obj, "markersize")) - fprintf (plot_stream, " pointsize %f", obj.markersize / 3); - endif - endif - else - if (! found_style) - fputs (plot_stream, " default"); - endif - fputs (plot_stream, ";\n"); - if (!isempty (style {sidx})) - sidx ++; - idx ++; - else - fputs (plot_stream, ";\n"); - endif - fprintf (plot_stream, "set style line %d default;\n", idx); - fprintf (plot_stream, "set style line %d", idx); - if (! mono) - if (strncmp (obj.markeredgecolor, "auto", 4)) - fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", - round (255*color)); - elseif (isnumeric (obj.markeredgecolor) && ! mono) - fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", - round (255*obj.markeredgecolor)); - endif - endif - if (! isempty (pt)) - style {sidx} = "points"; - fprintf (plot_stream, " pointtype %s", pt); - endif - if (isfield (obj, "markersize")) - fprintf (plot_stream, " pointsize %f", obj.markersize / 3); - endif - endif - endif - else - style{1} = errbars; - fputs (plot_stream, " pointtype 0"); - endif - - if (! found_style && isempty (style {1})) - fputs (plot_stream, " default"); - endif - - fputs (plot_stream, ";\n"); - -endfunction - -function [pt, pt2, obj] = gnuplot_pointtype (obj) - if (isfield (obj, "marker")) - switch (obj.marker) - case "+" - pt = pt2 = "1"; - case "o" - pt = "6"; - pt2 = "7"; - case "*" - pt = pt2 = "3"; - case "." - pt = "6"; - pt2 = "7"; - if (isfield (obj, "markerfacecolor") - || strncmp (obj.markerfacecolor, "none", 4)) - obj.markerfacecolor = "auto"; - endif - if (isfield (obj, "markersize")) - obj.markersize /= 3; - else - obj.markersize = 5; - endif - case "x" - pt = pt2 = "2"; - case {"square", "s"} - pt = "4"; - pt2 = "5"; - case {"diamond", "d"} - pt = "12"; - pt2 = "13"; - case "^" - pt = "8"; - pt2 = "9"; - case "v" - pt = "10"; - pt2 = "11"; - case ">" - ## FIXME -- should be triangle pointing right, use triangle pointing up - pt = "8"; - pt2 = "9"; - case "<" - ## FIXME -- should be triangle pointing left, use triangle pointing down - pt = "10"; - pt2 = "11"; - case {"pentagram", "p"} - ## FIXME -- should be pentagram, using pentagon - pt = "14"; - pt2 = "15"; - case {"hexagram", "h"} - ## FIXME -- should be 6 pt start, using "*" instead - pt = pt2 = "3"; - case "none" - pt = pt2 = ""; - otherwise - pt = pt2 = ""; - endswitch - else - pt = pt2 = ""; - endif -endfunction - -function __gnuplot_write_data__ (plot_stream, data, nd, parametric, cdata) - - ## DATA is already transposed. - - ## FIXME -- this may need to be converted to C++ for speed. - - ## Convert NA elements to normal NaN values because fprintf writes - ## "NA" and that confuses gnuplot. - idx = find (isna (data)); - if (any (idx)) - data(idx) = NaN; - endif - - if (nd == 2) - fwrite (plot_stream, data, "float64"); - elseif (nd == 3) - if (parametric) - fwrite (plot_stream, data, "float64"); - else - nr = rows (data); - if (cdata) - for j = 1:4:nr - fwrite (plot_stream, data(j:j+3,:), "float64"); - endfor - else - for j = 1:3:nr - fwrite (plot_stream, data(j:j+2,:), "float64"); - endfor - endif - endif - endif - -endfunction - -function do_tics (obj, plot_stream, ymirror, mono, gnuplot_term) - - obj.xticklabel = ticklabel_to_cell (obj.xticklabel); - obj.yticklabel = ticklabel_to_cell (obj.yticklabel); - obj.zticklabel = ticklabel_to_cell (obj.zticklabel); - - if (strcmp (obj.xminorgrid, "on")) - obj.xminortick = "on"; - endif - if (strcmp (obj.yminorgrid, "on")) - obj.yminortick = "on"; - endif - if (strcmp (obj.zminorgrid, "on")) - obj.zminortick = "on"; - endif - - [fontname, fontsize] = get_fontname_and_size (obj); - fontspec = create_fontspec (fontname, fontsize, gnuplot_term); - - ## A Gnuplot tic scale of 69 is equivalent to Octave's 0.5. - ticklength = sprintf ("scale %4.1f", (69/0.5)*obj.ticklength(1)); - - if (strcmpi (obj.xaxislocation, "top")) - do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, - obj.xticklabel, obj.xcolor, "x2", plot_stream, true, mono, - "border", obj.tickdir, ticklength, fontname, fontspec, - obj.interpreter, obj.xscale); - do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, - obj.xcolor, "x", plot_stream, true, mono, "border", - "", "", fontname, fontspec, obj.interpreter, obj.xscale); - elseif (strcmpi (obj.xaxislocation, "zero")) - do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, - obj.xticklabel, obj.xcolor, "x", plot_stream, true, mono, - "axis", obj.tickdir, ticklength, fontname, fontspec, - obj.interpreter, obj.xscale); - do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, - obj.xcolor, "x2", plot_stream, true, mono, "axis", - "", "", fontname, fontspec, obj.interpreter, obj.xscale); - else - do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, - obj.xticklabel, obj.xcolor, "x", plot_stream, true, mono, - "border", obj.tickdir, ticklength, fontname, fontspec, - obj.interpreter, obj.xscale); - do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, - obj.xcolor, "x2", plot_stream, true, mono, "border", - "", "", fontname, fontspec, obj.interpreter, obj.xscale); - endif - if (strcmpi (obj.yaxislocation, "right")) - do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, - obj.yticklabel, obj.ycolor, "y2", plot_stream, ymirror, mono, - "border", obj.tickdir, ticklength, fontname, fontspec, - obj.interpreter, obj.yscale); - do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, - obj.ycolor, "y", plot_stream, ymirror, mono, "border", - "", "", fontname, fontspec, obj.interpreter, obj.yscale); - elseif (strcmpi (obj.yaxislocation, "zero")) - do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, - obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, mono, - "axis", obj.tickdir, ticklength, fontname, fontspec, - obj.interpreter, obj.yscale); - do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, - obj.ycolor, "y2", plot_stream, ymirror, mono, "axis", - "", "", fontname, fontspec, obj.interpreter, obj.yscale); - else - do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, - obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, mono, - "border", obj.tickdir, ticklength, fontname, fontspec, - obj.interpreter, obj.yscale); - do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, - obj.ycolor, "y2", plot_stream, ymirror, mono, "border", - "", "", fontname, fontspec, obj.interpreter, obj.yscale); - endif - do_tics_1 (obj.ztickmode, obj.ztick, obj.zminortick, obj.zticklabelmode, - obj.zticklabel, obj.zcolor, "z", plot_stream, true, mono, - "border", obj.tickdir, ticklength, fontname, fontspec, - obj.interpreter, obj.zscale); -endfunction - -function do_tics_1 (ticmode, tics, mtics, labelmode, labels, color, ax, - plot_stream, mirror, mono, axispos, tickdir, ticklength, - fontname, fontspec, interpreter, scale) - persistent warned_latex = false; - if (strcmpi (interpreter, "tex")) - for n = 1 : numel(labels) - labels{n} = __tex2enhanced__ (labels{n}, fontname, false, false); - endfor - elseif (strcmpi (interpreter, "latex")) - if (! warned_latex) - warning ("latex markup not supported for tick marks"); - warned_latex = true; - endif - endif - if (strcmp (scale, "log")) - fmt = "10^{%T}"; - num_mtics = 10; - else - fmt = "%g"; - num_mtics = 5; - endif - colorspec = get_text_colorspec (color, mono); - if (strcmpi (ticmode, "manual") || strcmpi (labelmode, "manual")) - if (isempty (tics)) - fprintf (plot_stream, "unset %stics;\nunset m%stics;\n", ax, ax); - elseif (strcmpi (labelmode, "manual")) - if (ischar (labels)) - labels = cellstr (labels); - endif - if (isnumeric (labels)) - labels = num2str (real (labels(:))); - endif - if (ischar (labels)) - labels = permute (cellstr (labels), [2, 1]); - endif - if (iscellstr (labels)) - k = 1; - ntics = numel (tics); - nlabels = numel (labels); - fprintf (plot_stream, "set format %s \"%%s\";\n", ax); - if (mirror) - fprintf (plot_stream, "set %stics %s %s %s mirror (", ax, - tickdir, ticklength, axispos); - else - fprintf (plot_stream, "set %stics %s %s %s nomirror (", ax, - tickdir, ticklength, axispos); - endif - - labels = regexprep(labels, '%', "%%"); - for i = 1:ntics - fprintf (plot_stream, " \"%s\" %.15g", labels{k++}, tics(i)); - if (i < ntics) - fputs (plot_stream, ", "); - endif - if (k > nlabels) - k = 1; - endif - endfor - fprintf (plot_stream, ") %s %s;\n", colorspec, fontspec); - if (strcmp (mtics, "on")) - fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics); - else - fprintf (plot_stream, "unset m%stics;\n", ax); - endif - else - error ("__go_draw_axes__: unsupported type of ticklabel"); - endif - else - fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt); - if (mirror) - fprintf (plot_stream, "set %stics %s %s %s mirror (", ax, tickdir, - ticklength, axispos); - else - fprintf (plot_stream, "set %stics %s %s %s nomirror (", ax, tickdir, - ticklength, axispos); - endif - fprintf (plot_stream, " %.15g,", tics(1:end-1)); - fprintf (plot_stream, " %.15g) %s;\n", tics(end), fontspec); - if (strcmp (mtics, "on")) - fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics); - else - fprintf (plot_stream, "unset m%stics;\n", ax); - endif - endif - else - fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt); - if (mirror) - fprintf (plot_stream, "set %stics %s %s %s mirror %s %s;\n", ax, - axispos, tickdir, ticklength, colorspec, fontspec); - else - fprintf (plot_stream, "set %stics %s %s %s nomirror %s %s;\n", ax, - tickdir, ticklength, axispos, colorspec, fontspec); - endif - if (strcmp (mtics, "on")) - fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics); - else - fprintf (plot_stream, "unset m%stics;\n", ax); - endif - endif -endfunction - -function ticklabel = ticklabel_to_cell (ticklabel) - if (isnumeric (ticklabel)) - ## Use upto 5 significant digits - ticklabel = num2str (ticklabel(:), 5); - endif - if (ischar (ticklabel)) - if (size (ticklabel, 1) == 1 && any (ticklabel == "|")) - n = setdiff (findstr (ticklabel, "|"), findstr (ticklabel, '\|')); - ticklabel = strsplit (ticklabel, "|"); - else - ticklabel = cellstr (ticklabel); - endif - elseif (isempty (ticklabel)) - ticklabel = {""}; - else - ticklabel = ticklabel; - endif -endfunction - -function colorspec = get_text_colorspec (color, mono) - if (mono) - colorspec = ""; - else - colorspec = sprintf ("textcolor rgb \"#%02x%02x%02x\"", - round (255*color)); - endif -endfunction - -function [f, s, fnt, it, bld] = get_fontname_and_size (t) - if (isempty (t.fontname) || strcmp (t.fontname, "*")) - fnt = "{}"; - else - fnt = t.fontname; - endif - f = fnt; - it = false; - bld = false; - if (! isempty (t.fontweight) && strcmpi (t.fontweight, "bold")) - if (! isempty(t.fontangle) - && (strcmpi (t.fontangle, "italic") - || strcmpi (t.fontangle, "oblique"))) - f = cstrcat (f, "-bolditalic"); - it = true; - bld = true; - else - f = cstrcat (f, "-bold"); - bld = true; - endif - elseif (! isempty(t.fontangle) - && (strcmpi (t.fontangle, "italic") - || strcmpi (t.fontangle, "oblique"))) - f = cstrcat (f, "-italic"); - it = true; - endif - if (isempty (t.fontsize)) - s = 10; - else - s = t.fontsize; - endif -endfunction - -function [str, f, s] = __maybe_munge_text__ (enhanced, obj, fld) - - persistent warned_latex = false; - - if (strcmp (fld, "string")) - [f, s, fnt, it, bld] = get_fontname_and_size (obj); - else - f = "Helvetica"; - s = 10; - fnt = f; - it = false; - bld = false; - endif - - str = getfield (obj, fld); - if (enhanced) - if (strcmpi (obj.interpreter, "tex")) - str = __tex2enhanced__ (str, fnt, it, bld); - elseif (strcmpi (obj.interpreter, "latex")) - if (! warned_latex) - warning ("latex markup not supported for text objects"); - warned_latex = true; - endif - endif - endif -endfunction - -function str = __tex2enhanced__ (str, fnt, it, bld) - persistent sym = __setup_sym_table__ (); - persistent flds = fieldnames (sym); - - [s, e, m] = regexp(str,'\\([a-zA-Z]+|0)','start','end','matches'); - - for i = length (s) : -1 : 1 - ## special case for "\0" and replace with "{/Symbol \306}' - if (strncmp (m{i}, '\0', 2)) - str = cstrcat (str(1:s(i) - 1), '{/Symbol \306}', str(s(i) + 2:end)); - else - f = m{i}(2:end); - if (isfield (sym, f)) - g = getfield(sym, f); - ## FIXME The symbol font doesn't seem to support bold or italic - ##if (bld) - ## if (it) - ## g = regexprep (g, '/Symbol', '/Symbol-bolditalic'); - ## else - ## g = regexprep (g, '/Symbol', '/Symbol-bold'); - ## endif - ##elseif (it) - ## g = regexprep (g, '/Symbol', '/Symbol-italic'); - ##endif - str = cstrcat (str(1:s(i) - 1), g, str(e(i) + 1:end)); - elseif (strncmp (f, "rm", 2)) - bld = false; - it = false; - str = cstrcat (str(1:s(i) - 1), '/', fnt, ' ', str(s(i) + 3:end)); - elseif (strncmp (f, "it", 2) || strncmp (f, "sl", 2)) - it = true; - if (bld) - str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bolditalic ', - str(s(i) + 3:end)); - else - str = cstrcat (str(1:s(i) - 1), '/', fnt, '-italic ', - str(s(i) + 3:end)); - endif - elseif (strncmp (f, "bf", 2)) - bld = true; - if (it) - str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bolditalic ', - str(2(i) + 3:end)); - else - str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bold ', - str(s(i) + 3:end)); - endif - elseif (strcmpi (f, "color")) - ## FIXME Ignore \color but remove trailing {} block as well - d = strfind(str(e(i) + 1:end),'}'); - if (isempty (d)) - warning ('syntax error in \color argument'); - else - str = cstrcat (str(1:s(i) - 1), str(e(i) + d + 1:end)); - endif - elseif(strcmpi (f, "fontname")) - b1 = strfind(str(e(i) + 1:end),'{'); - b2 = strfind(str(e(i) + 1:end),'}'); - if (isempty(b1) || isempty(b2)) - warning ('syntax error in \fontname argument'); - else - str = cstrcat (str(1:s(i) - 1), '/', - str(e(i)+b1(1) + 1:e(i)+b2(1)-1), '{}', - str(e(i) + b2(1) + 1:end)); - endif - elseif(strcmpi (f, "fontsize")) - b1 = strfind(str(e(i) + 1:end),'{'); - b2 = strfind(str(e(i) + 1:end),'}'); - if (isempty(b1) || isempty(b2)) - warning ('syntax error in \fontname argument'); - else - str = cstrcat (str(1:s(i) - 1), '/=', - str(e(i)+b1(1) + 1:e(i)+b2(1)-1), '{}', - str(e(i) + b2(1) + 1:end)); - endif - else - ## Last desperate attempt to treat the symbol. Look for things - ## like \pix, that should be translated to the symbol Pi and x - for j = 1 : length (flds) - if (strncmp (flds{j}, f, length (flds{j}))) - g = getfield(sym, flds{j}); - ## FIXME The symbol font doesn't seem to support bold or italic - ##if (bld) - ## if (it) - ## g = regexprep (g, '/Symbol', '/Symbol-bolditalic'); - ## else - ## g = regexprep (g, '/Symbol', '/Symbol-bold'); - ## endif - ##elseif (it) - ## g = regexprep (g, '/Symbol', '/Symbol-italic'); - ##endif - str = cstrcat (str(1:s(i) - 1), g, - str(s(i) + length (flds{j}) + 1:end)); - break; - endif - endfor - endif - endif - endfor - - ## Prepend @ to things things like _0^x or _{-100}^{100} for - ## alignment But need to put the shorter of the two arguments first. - ## Carful of nested {} and unprinted characters when defining - ## shortest.. Don't have to worry about things like ^\theta as they - ## are already converted to ^{/Symbol q}. - - ## FIXME -- This is a mess... Is it worth it just for a "@" character? - - [s, m] = regexp(str,'[_\^]','start','matches'); - i = 1; - p = 0; - while (i < length (s)) - if (i < length(s)) - if (str(s(i) + p + 1) == "{") - s1 = strfind(str(s(i) + p + 2:end),'{'); - si = 1; - l1 = strfind(str(s(i) + p + 1:end),'}'); - li = 1; - while (li <= length (l1) && si <= length (s1)) - if (l1(li) < s1(si)) - if (li == si) - break; - endif - li++; - else - si++; - endif - endwhile - l1 = l1 (min (length(l1), si)); - if (s(i) + l1 + 1 == s(i+1)) - if (str(s(i + 1) + p + 1) == "{") - s2 = strfind(str(s(i + 1) + p + 2:end),'{'); - si = 1; - l2 = strfind(str(s(i + 1) + p + 1:end),'}'); - li = 1; - while (li <= length (l2) && si <= length (s2)) - if (l2(li) < s2(si)) - if (li == si) - break; - endif - li++; - else - si++; - endif - endwhile - l2 = l2 (min (length(l2), si)); - if (length_string (str(s(i)+p+2:s(i)+p+l1-1)) <= - length_string(str(s(i+1)+p+2:s(i+1)+p+l2-1))) - ## Shortest already first! - str = cstrcat (str(1:s(i)+p-1), "@", str(s(i)+p:end)); - else - ## Have to swap sub/super-script to get shortest first. - str = cstrcat (str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+l2), - str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+l2+1:end)); - endif - else - ## Have to swap sub/super-script to get shortest first. - str = cstrcat (str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+1), - str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+2:end)); - endif - i += 2; - p ++; - else - i++; - endif - else - if (s(i+1) == s(i) + 2) - ## Shortest already first! - str = cstrcat (str(1:s(i)+p-1), "@", str(s(i)+p:end)); - p ++; - i += 2; - else - i ++; - endif - endif - else - i ++; - endif - endwhile - -endfunction - -function l = length_string (s) - l = length (s) - length (strfind(s,'{')) - length (strfind(s,'}')); - m = regexp (s, '/([\w-]+|[\w-]+=\d+)', 'matches'); - if (!isempty (m)) - l = l - sum (cellfun (@length, m)); - endif -endfunction - -function sym = __setup_sym_table__ () - ## Setup the translation table for TeX to gnuplot enhanced mode. - sym.forall = '{/Symbol \042}'; - sym.exists = '{/Symbol \044}'; - sym.ni = '{/Symbol \047}'; - sym.cong = '{/Symbol \100}'; - sym.Delta = '{/Symbol D}'; - sym.Phi = '{/Symbol F}'; - sym.Gamma = '{/Symbol G}'; - sym.vartheta = '{/Symbol J}'; - sym.Lambda = '{/Symbol L}'; - sym.Pi = '{/Symbol P}'; - sym.Theta = '{/Symbol Q}'; - sym.Sigma = '{/Symbol S}'; - sym.varsigma = '{/Symbol V}'; - sym.Omega = '{/Symbol W}'; - sym.Xi = '{/Symbol X}'; - sym.Psi = '{/Symbol Y}'; - sym.perp = '{/Symbol \136}'; - sym.alpha = '{/Symbol a}'; - sym.beta = '{/Symbol b}'; - sym.chi = '{/Symbol c}'; - sym.delta = '{/Symbol d}'; - sym.epsilon = '{/Symbol e}'; - sym.phi = '{/Symbol f}'; - sym.gamma = '{/Symbol g}'; - sym.eta = '{/Symbol h}'; - sym.iota = '{/Symbol i}'; - sym.varphi = '{/Symbol j}'; - sym.kappa = '{/Symbol k}'; - sym.lambda = '{/Symbol l}'; - sym.mu = '{/Symbol m}'; - sym.nu = '{/Symbol n}'; - sym.o = '{/Symbol o}'; - sym.pi = '{/Symbol p}'; - sym.theta = '{/Symbol q}'; - sym.rho = '{/Symbol r}'; - sym.sigma = '{/Symbol s}'; - sym.tau = '{/Symbol t}'; - sym.upsilon = '{/Symbol u}'; - sym.varpi = '{/Symbol v}'; - sym.omega = '{/Symbol w}'; - sym.xi = '{/Symbol x}'; - sym.psi = '{/Symbol y}'; - sym.zeta = '{/Symbol z}'; - sym.sim = '{/Symbol \176}'; - sym.Upsilon = '{/Symbol \241}'; - sym.prime = '{/Symbol \242}'; - sym.leq = '{/Symbol \243}'; - sym.infty = '{/Symbol \245}'; - sym.clubsuit = '{/Symbol \247}'; - sym.diamondsuit = '{/Symbol \250}'; - sym.heartsuit = '{/Symbol \251}'; - sym.spadesuit = '{/Symbol \252}'; - sym.leftrightarrow = '{/Symbol \253}'; - sym.leftarrow = '{/Symbol \254}'; - sym.uparrow = '{/Symbol \255}'; - sym.rightarrow = '{/Symbol \256}'; - sym.downarrow = '{/Symbol \257}'; - sym.circ = '{/Symbol \260}'; - sym.pm = '{/Symbol \261}'; - sym.geq = '{/Symbol \263}'; - sym.times = '{/Symbol \264}'; - sym.propto = '{/Symbol \265}'; - sym.partial = '{/Symbol \266}'; - sym.bullet = '{/Symbol \267}'; - sym.div = '{/Symbol \270}'; - sym.neq = '{/Symbol \271}'; - sym.equiv = '{/Symbol \272}'; - sym.approx = '{/Symbol \273}'; - sym.ldots = '{/Symbol \274}'; - sym.mid = '{/Symbol \275}'; - sym.aleph = '{/Symbol \300}'; - sym.Im = '{/Symbol \301}'; - sym.Re = '{/Symbol \302}'; - sym.wp = '{/Symbol \303}'; - sym.otimes = '{/Symbol \304}'; - sym.oplus = '{/Symbol \305}'; - sym.oslash = '{/Symbol \306}'; - sym.cap = '{/Symbol \307}'; - sym.cup = '{/Symbol \310}'; - sym.supset = '{/Symbol \311}'; - sym.supseteq = '{/Symbol \312}'; - sym.subset = '{/Symbol \314}'; - sym.subseteq = '{/Symbol \315}'; - sym.in = '{/Symbol \316}'; - sym.notin = '{/Symbol \317}'; - sym.angle = '{/Symbol \320}'; - sym.bigtriangledown = '{/Symbol \321}'; - sym.langle = '{/Symbol \341}'; - sym.rangle = '{/Symbol \361}'; - sym.nabla = '{/Symbol \321}'; - sym.prod = '{/Symbol \325}'; - sym.surd = '{/Symbol \326}'; - sym.cdot = '{/Symbol \327}'; - sym.neg = '{/Symbol \330}'; - sym.wedge = '{/Symbol \331}'; - sym.vee = '{/Symbol \332}'; - sym.Leftrightarrow = '{/Symbol \333}'; - sym.Leftarrow = '{/Symbol \334}'; - sym.Uparrow = '{/Symbol \335}'; - sym.Rightarrow = '{/Symbol \336}'; - sym.Downarrow = '{/Symbol \337}'; - sym.diamond = '{/Symbol \340}'; - sym.copyright = '{/Symbol \343}'; - sym.lfloor = '{/Symbol \353}'; - sym.lceil = '{/Symbol \351}'; - sym.rfloor = '{/Symbol \373}'; - sym.rceil = '{/Symbol \371}'; - sym.int = '{/Symbol \362}'; -endfunction - -function retval = __do_enhanced_option__ (enhanced, obj) - retval = ""; - if (enhanced) - if (strcmpi (obj.interpreter, "none")) - retval = "noenhanced"; - else - retval = "enhanced"; - endif - endif -endfunction
--- a/scripts/plot/__go_draw_figure__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,198 +0,0 @@ -## Copyright (C) 2005-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} __go_draw_figure__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono}) -## Undocumented internal function. -## @end deftypefn - -## Author: jwe - -function __go_draw_figure__ (h, plot_stream, enhanced, mono) - - if (nargin == 4) - htype = get (h, "type"); - if (strcmp (htype, "figure")) - ## Get complete list of children. - kids = allchild (h); - nkids = length (kids); - - if (nkids > 0) - fputs (plot_stream, "\nreset;\n"); - fputs (plot_stream, "set autoscale keepfix;\n"); - fputs (plot_stream, "set origin 0, 0\n"); - fputs (plot_stream, "set size 1, 1\n"); - bg = get (h, "color"); - if (isnumeric (bg)) - fprintf (plot_stream, "set obj 1 rectangle from screen 0,0 to screen 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * bg); - bg_is_set = true; - else - bg_is_set = false; - endif - - for i = nkids:-1:1 - type = get (kids(i), "type"); - switch (type) - case "axes" - if (strcmpi (get (kids (i), "tag"), "legend")) - ## This is so ugly. If there was a way of getting - ## gnuplot to give us the text extents of strings - ## then we could get rid of this mess. - lh = getfield (get (kids(i), "userdata"), "handle"); - if (isscalar (lh)) - ## We have a legend with a single parent. It'll be handled - ## below as a gnuplot key to the axis it corresponds to - continue; - else - ca = lh(1); - ## Rely upon listener to convert axes position - ## to "normalized" units. - legend_axes_units = get (kids(i), "units"); - legend_axes_position = get (kids(i), "position"); - legend_axes_outerposition = get (kids(i), "outerposition"); - legend_axes_box = get (kids(i), "box"); - legend_axes_ylim = get (kids(i), "ylim"); - orig_axes_units = get (ca, "units"); - hlgnd = get (kids(i)); - - unwind_protect - set (ca, "units", "normalized"); - set (kids(i), "units", "normalized", "box", "off", - "ylim", [-2, -1], "position", get (ca(1), "position"), - "outerposition", get (ca(1), "outerposition")); - - ## Create a new set of lines with the appropriate - ## displaynames, etc - toberm = []; - hobj = get (kids(i), "children"); - for j = numel (hobj) : -1 : 1 - if (! strcmp (get (hobj(j), "type"), "text")) - continue; - endif - displayname = get (hobj(j), "string"); - ll = []; - lm = []; - for k = numel (hobj) : -1 : 1 - if (! strcmp (get (hobj(k), "type"), "line")) - continue; - endif - if (get (hobj(j), "userdata") - != get (hobj(k), "userdata")) - continue; - endif - if (! strcmp (get (hobj(k), "linestyle"), "none")) - ll = hobj(k); - endif - if (! strcmp (get (hobj(k), "marker"), "none")) - lm = hobj(k); - endif - endfor - - if (! isempty (ll)) - if (!isempty (lm)) - toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", get(ll,"linestyle"), "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))]; - else - toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(ll,"color"), "linestyle", get(ll,"linestyle"), "marker", "none", "displayname", displayname, "parent", kids(i))]; - endif - elseif (! isempty (lm)) - toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", "none", "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))]; - endif - endfor - if (bg_is_set) - fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg)); - endif - __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, - bg_is_set, false, hlgnd); - unwind_protect_cleanup - ## Return axes "units" and "position" back to - ## their original values. - set (ca, "units", orig_axes_units); - set (kids(i), "units", legend_axes_units, - "box", legend_axes_box, - "ylim", legend_axes_ylim, - "position", legend_axes_position, - "outerposition", legend_axes_outerposition); - delete (toberm); - bg_is_set = false; - end_unwind_protect - endif - else - ## Rely upon listener to convert axes position - ## to "normalized" units. - orig_axes_units = get (kids(i), "units"); - orig_axes_position = get (kids(i), "position"); - unwind_protect - set (kids(i), "units", "normalized"); - fg = get (kids(i), "color"); - if (isnumeric (fg) && strcmp (get (kids(i), "visible"), "on")) - fprintf (plot_stream, "set obj 2 rectangle from graph 0,0 to graph 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * fg); - fg_is_set = true; - else - fg_is_set = false; - endif - if (bg_is_set) - fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg)); - endif - ## Find if this axes has an associated legend axes and pass it - ## to __go_draw_axes__ - hlegend = []; - fkids = get (h, "children"); - for j = 1 : numel(fkids) - if (ishandle (fkids (j)) - && strcmp (get (fkids (j), "type"), "axes") - && (strcmp (get (fkids (j), "tag"), "legend"))) - udata = get (fkids (j), "userdata"); - if (isscalar(udata.handle) - && ! isempty (intersect (udata.handle, kids (i)))) - hlegend = get (fkids (j)); - break; - endif - endif - endfor - __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, - bg_is_set, fg_is_set, hlegend); - unwind_protect_cleanup - ## Return axes "units" and "position" back to - ## their original values. - set (kids(i), "units", orig_axes_units); - set (kids(i), "position", orig_axes_position); - bg_is_set = false; - fg_is_set = false; - end_unwind_protect - endif - case "uimenu" - ## ignore uimenu objects - otherwise - error ("__go_draw_figure__: unknown object class, %s", type); - endswitch - endfor - fputs (plot_stream, "\nunset multiplot;\n"); - else - fputs (plot_stream, "\nreset; clear;\n"); - fflush (plot_stream); - endif - else - error ("__go_draw_figure__: expecting figure object, found `%s'", - htype); - endif - else - print_usage (); - endif - -endfunction -
--- a/scripts/plot/__marching_cube__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,530 +0,0 @@ -## Copyright (C) 2009-2011 Martin Helm -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{t}, @var{p}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}) -## @deftypefnx {Function File} {[@var{t}, @var{p}, @var{c}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col}) -## Undocumented internal function. -## @end deftypefn - -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{t}, @var{p}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}) -## @deftypefnx {Function File} {[@var{t}, @var{p}, @var{c}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col}) -## -## Return the triangulation information @var{t} at points @var{p} for -## the isosurface values resp. the volume data @var{val} and the iso -## level @var{iso}. It is considered that the volume data @var{val} is -## given at the points @var{x}, @var{y} and @var{z} which are of type -## three--dimensional numeric arrays. The orientation of the triangles -## is choosen such that the normals point from the higher values to the -## lower values. -## -## Optionally the color data @var{col} can be passed to this function -## whereas computed vertices color data @var{c} is returned as third -## argument. -## -## The marching cube algorithm is well known and described, for example, at -## Wikipedia. The triangulation lookup table and the edge table used -## here are based on Cory Gene Bloyd's implementation and can be found -## beyond other surface and geometry stuff at Paul Bourke's website -## @uref{http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise}. -## -## For example: -## -## @example -## @group -## N = 20; -## lin = linspace(0, 2, N); -## [x, y, z] = meshgrid (lin, lin, lin); -## -## c = (x-.5).^2 + (y-.5).^2 + (z-.5).^2; -## [t, p] = __marching_cube__ (x, y, z, c, .5); -## -## figure (); -## trimesh (t, p(:,1), p(:,2), p(:,3)); -## @end group -## @end example -## -## Instead of the @command{trimesh} function the @command{patch} -## function can be used to visualize the geometry. For example: -## -## @example -## @group -## figure (); view (-38, 20); -## pa = patch ("Faces", t, "Vertices", p, "FaceVertexCData", p, \ -## "FaceColor", "interp", "EdgeColor", "none"); -## -## ## Revert normals -## set (pa, "VertexNormals", -get(pa, "VertexNormals")); -## -## ## Set lightning (available with the JHandles package) -## # set (pa, "FaceLighting", "gouraud"); -## # light( "Position", [1 1 5]); -## @end group -## @end example -## -## @end deftypefn - -## Author: Martin Helm <martin@mhelm.de> - -function [T, p, col] = __marching_cube__ (xx, yy, zz, c, iso, colors) - - persistent edge_table=[]; - persistent tri_table=[]; - - calc_cols = false; - lindex = 4; - - if (isempty (tri_table) || isempty (edge_table)) - [edge_table, tri_table] = init_mc (); - endif - - if ((nargin != 5 && nargin != 6) || (nargout != 2 && nargout != 3)) - print_usage (); - endif - - if (!ismatrix (xx) || !ismatrix (yy) || !ismatrix (zz) || !ismatrix (c) || ... - ndims (xx) != 3 || ndims (yy) != 3 || ndims (zz) != 3 || ndims (c) != 3) - error ("__marching_cube__: XX, YY, ZZ, C must be matrices of dim 3"); - endif - - if (!size_equal (xx, yy, zz, c)) - error ("__marching_cube__: XX, YY, ZZ, C must be of equal size"); - endif - - if (any (size (xx) < [2 2 2])) - error ("__marching_cube__: grid size must be at least 2x2x2"); - endif - - if (!isscalar (iso)) - error ("__marching_cube__: ISO must be scalar value"); - endif - - if (nargin == 6) - if ( !ismatrix (colors) || ndims (colors) != 3 || size (colors) != size (c) ) - error ( "COLORS must be a matrix of dim 3 and of same size as C" ); - endif - calc_cols = true; - lindex = 5; - endif - - n = size (c) - 1; - - ## phase I: assign information to each voxel which edges are intersected by - ## the isosurface - cc = zeros (n(1), n(2), n(3), "uint16"); - cedge = zeros (size (cc), "uint16"); - - vertex_idx = {1:n(1), 1:n(2), 1:n(3); ... - 2:n(1)+1, 1:n(2), 1:n(3); ... - 2:n(1)+1, 2:n(2)+1, 1:n(3); ... - 1:n(1), 2:n(2)+1, 1:n(3); ... - 1:n(1), 1:n(2), 2:n(3)+1; ... - 2:n(1)+1, 1:n(2), 2:n(3)+1; ... - 2:n(1)+1, 2:n(2)+1, 2:n(3)+1; ... - 1:n(1), 2:n(2)+1, 2:n(3)+1 }; - - ## calculate which vertices have values higher than iso - for ii=1:8 - idx = c(vertex_idx{ii, :}) > iso; - cc(idx) = bitset (cc(idx), ii); - endfor - - cedge = edge_table(cc+1); # assign the info about intersected edges - id = find (cedge); # select only voxels which are intersected - if (isempty (id)) - T = p = col = []; - return - endif - - ## phase II: calculate the list of intersection points - xyz_off = [1, 1, 1; 2, 1, 1; 2, 2, 1; 1, 2, 1; 1, 1, 2; 2, 1, 2; 2, 2, 2; 1, 2, 2]; - edges = [1 2; 2 3; 3 4; 4 1; 5 6; 6 7; 7 8; 8 5; 1 5; 2 6; 3 7; 4 8]; - offset = sub2ind (size (c), xyz_off(:, 1), xyz_off(:, 2), xyz_off(:, 3)) -1; - pp = zeros (length (id), lindex, 12); - ccedge = [vec(cedge(id)), id]; - ix_offset=0; - for jj=1:12 - id__ = bitget (ccedge(:, 1), jj); - id_ = ccedge(id__, 2); - [ix iy iz] = ind2sub (size (cc), id_); - id_c = sub2ind (size (c), ix, iy, iz); - id1 = id_c + offset(edges(jj, 1)); - id2 = id_c + offset(edges(jj, 2)); - if (calc_cols) - pp(id__, 1:5, jj) = [vertex_interp(iso, xx(id1), yy(id1), zz(id1), ... - xx(id2), yy(id2), zz(id2), c(id1), c(id2), colors(id1), colors(id2)), ... - (1:size (id_, 1))' + ix_offset ]; - else - pp(id__, 1:4, jj) = [vertex_interp(iso, xx(id1), yy(id1), zz(id1), ... - xx(id2), yy(id2), zz(id2), c(id1), c(id2)), ... - (1:size (id_, 1))' + ix_offset ]; - endif - ix_offset += size (id_, 1); - endfor - - ## phase III: calculate the triangulation from the point list - T = []; - tri = tri_table(cc(id)+1, :); - for jj=1:3:15 - id_ = find (tri(:, jj)>0); - p = [id_, lindex*ones(size (id_, 1), 1),tri(id_, jj:jj+2)]; - if (!isempty (p)) - p1 = sub2ind (size (pp), p(:,1), p(:,2), p(:,3)); - p2 = sub2ind (size (pp), p(:,1), p(:,2), p(:,4)); - p3 = sub2ind (size (pp), p(:,1), p(:,2), p(:,5)); - T = [T; pp(p1), pp(p2), pp(p3)]; - endif - endfor - - p = []; - col = []; - for jj = 1:12 - idp = pp(:, lindex, jj) > 0; - if (any (idp)) - p(pp(idp, lindex, jj), 1:3) = pp(idp, 1:3, jj); - if (calc_cols) - col(pp(idp, lindex, jj),1) = pp(idp, 4, jj); - endif - endif - endfor -endfunction - -function p = vertex_interp(isolevel,p1x, p1y, p1z,... - p2x, p2y, p2z,valp1,valp2, col1, col2) - - if (nargin == 9) - p = zeros (length (p1x), 3); - elseif (nargin == 11) - p = zeros (length (p1x), 4); - else - error ("__marching_cube__: wrong number of arguments"); - endif - mu = zeros (length (p1x), 1); - id = abs (valp1-valp2) < (10*eps) .* (abs (valp1) .+ abs (valp2)); - if (any (id)) - p(id, 1:3) = [ p1x(id), p1y(id), p1z(id) ]; - if (nargin == 11) - p(id, 4) = col1(id); - endif - endif - nid = !id; - if (any (nid)) - mu(nid) = (isolevel - valp1(nid)) ./ (valp2(nid) - valp1(nid)); - p(nid, 1:3) = [p1x(nid) + mu(nid) .* (p2x(nid) - p1x(nid)), ... - p1y(nid) + mu(nid) .* (p2y(nid) - p1y(nid)), ... - p1z(nid) + mu(nid) .* (p2z(nid) - p1z(nid))]; - if (nargin == 11) - p(nid, 4) = col1(nid) + mu(nid) .* (col2(nid) - col1(nid)); - endif - endif -endfunction - -function [edge_table, tri_table] = init_mc() - edge_table = [ - 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, ... - 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, ... - 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, ... - 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, ... - 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, ... - 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, ... - 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, ... - 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, ... - 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, ... - 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, ... - 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, ... - 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, ... - 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, ... - 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, ... - 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , ... - 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, ... - 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, ... - 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, ... - 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, ... - 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, ... - 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, ... - 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, ... - 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, ... - 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, ... - 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, ... - 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, ... - 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, ... - 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, ... - 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, ... - 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, ... - 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, ... - 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 ]; - - tri_table =[ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1; - 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1; - 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1; - 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1; - 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1; - 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1; - 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1; - 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1; - 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1; - 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1; - 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1; - 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1; - 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1; - 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1; - 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1; - 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1; - 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1; - 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1; - 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1; - 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1; - 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1; - 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1; - 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1; - 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1; - 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1; - 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1; - 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1; - 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1; - 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1; - 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1; - 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1; - 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1; - 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1; - 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1; - 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1; - 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1; - 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1; - 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1; - 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1; - 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1; - 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1; - 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1; - 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1; - 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1; - 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1; - 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1; - 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1; - 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1; - 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1; - 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1; - 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1; - 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1; - 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1; - 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1; - 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1; - 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1; - 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1; - 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1; - 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1; - 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1; - 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1; - 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1; - 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1; - 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1; - 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1; - 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1; - 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1; - 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1; - 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1; - 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1; - 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1; - 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1; - 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1; - 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1; - 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1; - 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1; - 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1; - 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1; - 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1; - 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1; - 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1; - 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1; - 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1; - 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1; - 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1; - 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1; - 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1; - 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1; - 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1; - 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1; - 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1; - 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1; - 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1; - 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1; - 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1; - 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1; - 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1; - 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1; - 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1; - 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1; - 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1; - 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1; - 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1; - 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1; - 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1; - 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1; - 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1; - 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1; - 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1; - 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1; - 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1; - 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1; - 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1; - 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1; - 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1; - 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1; - 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1; - 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1; - 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1; - 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1; - 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1; - 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1; - 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1; - 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1; - 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1; - 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1; - 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1; - 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1; - 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1; - 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1; - 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1; - 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1; - 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1; - 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1; - 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1; - 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1; - 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1; - 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1; - 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1; - 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1; - 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1; - 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1; - 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1; - 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1; - 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1; - 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1; - 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1; - 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1; - 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1; - 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1; - 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1; - 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1; - 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1; - 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1; - 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1; - 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1; - 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1; - 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1; - 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1; - 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1; - 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1; - 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1; - 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1; - 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1; - 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1; - 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1; - 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1; - 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1; - 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1; - 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1; - 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1; - 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1; - 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1; - 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1; - 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1; - 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1; - 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1; - 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1; - 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1; - 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ] + 1; -endfunction
--- a/scripts/plot/__next_line_color__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -## Copyright (C) 2007-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {@var{rgb} =} __next_line_color__ (@var{reset}) -## Undocumented internal function. -## @end deftypefn - -## Return the next line color in the rotation. - -## Author: jwe - -function rgb = __next_line_color__ (reset) - - persistent color_rotation; - persistent num_colors; - persistent color_index; - - if (nargin < 2) - if (nargin == 1) - if (reset || isempty (color_rotation)) - color_rotation = get (gca (), "colororder"); - num_colors = rows (color_rotation); - color_index = 1; - endif - elseif (! isempty (color_rotation)) - rgb = color_rotation(color_index,:); - if (++color_index > num_colors) - color_index = 1; - __next_line_style__ ("incr"); - endif - else - error ("__next_line_color__: color_rotation not initialized"); - endif - else - print_usage (); - endif - -endfunction
--- a/scripts/plot/__next_line_style__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -## Copyright (C) 2010-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {@var{style} =} __next_line_style__ (@var{reset}) -## Undocumented internal function. -## @end deftypefn - -## Return the next line style in the rotation. - - -function [linestyle, marker] = __next_line_style__ (reset) - - persistent style_rotation; - persistent num_styles; - persistent style_index; - - if (nargin < 2) - if (nargin == 1) - if (ischar (reset) && strncmp (reset, "incr", 4)) - if (isempty (style_rotation)) - error ("__next_line_style__: style_rotation not initialized"); - elseif (++style_index > num_styles) - style_index = 1; - endif - elseif (reset || isempty (style_rotation)) - style_rotation = strsplit (get (gca (), "linestyleorder"), "|"); - num_styles = length (style_rotation); - style_index = 1; - endif - elseif (! isempty (style_rotation)) - options = __pltopt__ ("__next_line_style__", - style_rotation (style_index)); - linestyle = options.linestyle; - marker = options.marker; - else - error ("__next_line_style__: style_rotation not initialized"); - endif - else - print_usage (); - endif - -endfunction
--- a/scripts/plot/__print_parse_opts__.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,609 +0,0 @@ -## Copyright (C) 2008-2011 David Bateman -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} ginput (@var{n}) -## Return which mouse buttons were pressed and keys were hit on the current -## figure. If @var{n} is defined, then wait for @var{n} mouse clicks -## before returning. If @var{n} is not defined, then @code{ginput} will -## loop until the return key is pressed. -## @end deftypefn - -function arg_st = __print_parse_opts__ (varargin) - - persistent warn_on_missing_binary = true - - arg_st.append_to_file = false; - arg_st.canvas_size = []; - arg_st.debug = false; - arg_st.debug_file = "octave-print-commands.log"; - arg_st.devopt = ""; - arg_st.epstool_binary = __quote_path__ (__find_binary__ ("epstool")); - arg_st.figure = get (0, "currentfigure"); - arg_st.fig2dev_binary = __quote_path__ (__find_binary__ ("fig2dev")); - arg_st.fontsize = ""; - arg_st.font = ""; - arg_st.force_solid = 0; # 0=default, -1=dashed, +1=solid - arg_st.formatted_for_printing = false; - arg_st.ghostscript.binary = __quote_path__ (__ghostscript_binary__ ()); - arg_st.ghostscript.debug = false; - arg_st.ghostscript.device = ""; - arg_st.ghostscript.epscrop = true; - arg_st.ghostscript.level = []; - arg_st.ghostscript.output = ""; - arg_st.ghostscript.papersize = ""; - arg_st.ghostscript.pageoffset = []; - arg_st.ghostscript.resolution = 150; - arg_st.ghostscript.antialiasing = false; - arg_st.loose = false; - arg_st.lpr_binary = __quote_path__ (__find_binary__ ("lpr")); - arg_st.name = ""; - arg_st.orientation = ""; - arg_st.pstoedit_binary = __quote_path__ (__find_binary__ ("pstoedit")); - arg_st.preview = ""; - arg_st.printer = ""; - arg_st.send_to_printer = false; - arg_st.special_flag = "textnormal"; - arg_st.tight_flag = false; - arg_st.use_color = 0; # 0=default, -1=mono, +1=color - - if (isunix ()) - arg_st.lpr_options = "-l"; - elseif (ispc ()) - arg_st.lpr_options = "-o l"; - else - arg_st.lpr_options = ""; - endif - arg_st.unlink = {}; - - if (nargin > 0 && isfigure (varargin{1})) - arg_st.figure = varargin{1}; - varargin(1) = []; - endif - - for i = 1:numel(varargin) - arg = strtrim (varargin{i}); - if (ischar (arg)) - if (strcmp (arg, "-color")) - arg_st.use_color = 1; - elseif (strcmp (arg, "-append")) - arg_st.append_to_file = true; - elseif (strcmp (arg, "-mono")) - arg_st.use_color = -1; - elseif (strcmp (arg, "-solid")) - arg_st.force_solid = 1; - elseif (strcmp (arg, "-dashed")) - arg_st.force_solid = -1; - elseif (strncmp (arg, "-portrait", numel (arg))) - arg_st.orientation = "portrait"; - elseif (strncmp (arg, "-landscape", numel (arg))) - arg_st.orientation = "landscape"; - elseif (strcmp (arg, "-loose")) - arg_st.loose = true; - arg_st.tight_flag = false; - elseif (strcmp (arg, "-tight")) - arg_st.loose = false; - arg_st.tight_flag = true; - elseif (strcmp (arg, "-textspecial")) - arg_st.special_flag = "textspecial"; - elseif (any (strcmp (arg, {"-interchange", "-metafile", "-pict", "-tiff"}))) - arg_st.preview = arg(2:end); - elseif (strncmp (arg, "-debug", 6)) - arg_st.debug = true; - arg_st.ghostscript.debug = true; - if (length (arg) > 7) - arg_st.debug_file = arg(8:end); - endif - elseif (length (arg) > 2 && arg(1:2) == "-d") - arg_st.devopt = tolower (arg(3:end)); - elseif (length (arg) > 2 && arg(1:2) == "-P") - arg_st.printer = arg; - elseif (strncmp (arg, "-EPSTOOL:", 9)) - arg_st.epstool_binary = arg{10:end}; - elseif (strncmp (arg, "-FIG2DEV:", 9)) - arg_st.fig2dev_binary = arg{10:end}; - elseif (strncmp (arg, "-PSTOEDIT:", 9)) - arg_st.pstoedit_binary = arg{10:end}; - elseif ((length (arg) > 2) && arg(1:2) == "-G") - arg_st.ghostscript.binary = file_in_path (getenv ("PATH"), arg(3:end)); - if (isempty (arg_st.ghostscript.binary)) - error ("print: Ghostscript binary ""%s"" could not be located", - arg(3:end)); - else - arg_st.ghostscript_binary = __quote_path__ (arg_st.ghostscript_binary); - endif - elseif (length (arg) > 2 && arg(1:2) == "-F") - idx = rindex (arg, ":"); - if (idx) - arg_st.font = arg(3:idx-1); - arg_st.fontsize = str2num (arg(idx+1:end)); - else - arg_st.font = arg(3:end); - endif - elseif (length (arg) > 2 && arg(1:2) == "-S") - arg_st.canvas_size = str2num (arg(3:end)); - elseif (length (arg) > 2 && arg(1:2) == "-r") - arg_st.ghostscript.resolution = str2double (arg(3:end)); - elseif (length (arg) > 2 && arg(1:2) == "-f") - arg_st.figure = str2num (arg(3:end)); - elseif (length (arg) >= 1 && arg(1) == "-") - error ("print: unknown option `%s'", arg); - elseif (length (arg) > 0) - arg_st.name = arg; - endif - elseif (isfigure (arg)) - arg_st.figure = arg; - else - error ("print: expecting inputs to be character string options or a figure handle"); - endif - endfor - - if (arg_st.ghostscript.resolution == 0) - ## Do as Matlab does. - arg_st.ghostscript.resolution = num2str (get (0, "screenpixelsperinch")); - endif - - if (isempty (arg_st.orientation)) - if (isfigure (arg_st.figure)) - arg_st.orientation = get (arg_st.figure, "paperorientation"); - else - ## Allows tests to be run without error. - arg_st.orientation = "portrait"; - endif - endif - - if (isempty (arg_st.ghostscript.binary)) - arg_st.ghostscript.binary = __ghostscript_binary__ (); - endif - - dot = rindex (arg_st.name, "."); - if (isempty (arg_st.devopt)) - if (dot == 0) - arg_st.devopt = "psc"; - else - arg_st.devopt = tolower (arg_st.name(dot+1:end)); - endif - endif - - if (arg_st.use_color == 0) - if (any (strcmp ({"ps", "ps2", "eps", "eps2"}, arg_st.devopt))) - arg_st.use_color = -1; - else - arg_st.use_color = 1; - endif - endif - - if (strcmp (arg_st.devopt, "tex")) - arg_st.devopt = "epslatex"; - elseif (strcmp (arg_st.devopt, "ill")) - arg_st.devopt = "aifm"; - elseif (strcmp (arg_st.devopt, "cdr")) - arg_st.devopt = "corel"; - elseif (strcmp (arg_st.devopt, "meta")) - arg_st.devopt = "emf"; - elseif (strcmp (arg_st.devopt, "jpg")) - arg_st.devopt = "jpeg"; - endif - - dev_list = {"aifm", "corel", "fig", "png", "jpeg", ... - "gif", "pbm", "pbmraw", "dxf", "mf", ... - "svg", "hpgl", "ps", "ps2", "psc", ... - "psc2", "eps", "eps2", "epsc", "epsc2", ... - "emf", "pdf", "pslatex", "epslatex", "epslatexstandalone", ... - "pslatexstandalone", "pdflatexstandalone", ... - "pstex", "tiff", "tiffn" "tikz", "pcxmono", ... - "pcx24b", "pcx256", "pcx16", "pgm", "pgmraw", ... - "ppm", "ppmraw", "pdflatex", "texdraw", ... - "pdfcairo", "pngcairo", "pstricks", ... - "epswrite", "pswrite", "ps2write", "pdfwrite"}; - - suffixes = {"ai", "cdr", "fig", "png", "jpg", ... - "gif", "pbm", "pbm", "dxf", "mf", ... - "svg", "hpgl", "ps", "ps", "ps", ... - "ps", "eps", "eps", "eps", "eps", ... - "emf", "pdf", "tex", "tex", "tex", ... - "tex", "tex", ... - "ps", "tiff", "tiff", "tikz", "pcx", ... - "pcx", "pcx", "pcx", "pgm", "pgm", ... - "ppm", "ppm", "tex", "tex", ... - "pdf", "png", "tex", ... - "eps", "ps", "ps", "pdf"}; - - if (isfigure (arg_st.figure)) - __graphics_toolkit__ = get (arg_st.figure, "__graphics_toolkit__"); - else - ## Allow tests when no figures are present. - __graphics_toolkit__ = get (0, "defaultfigure__graphics_toolkit__"); - endif - - if (strcmp (__graphics_toolkit__, "gnuplot") - && __gnuplot_has_feature__ ("epslatex_implies_eps_filesuffix")) - suffixes(strncmp (dev_list, "epslatex", 8)) = {"eps"}; - endif - - match = strcmpi (dev_list, arg_st.devopt); - if (any (match)) - default_suffix = suffixes {match}; - else - default_suffix = arg_st.devopt; - endif - - if (dot == 0 && ! isempty (arg_st.name)) - arg_st.name = strcat (arg_st.name, ".", default_suffix); - endif - - if (arg_st.append_to_file) - if (isempty (arg_st.name)) - arg_st.append_to_file = false; - elseif (any (strcmpi (arg_st.devopt, {"eps", "eps2", "epsc", "epsc2", ... - "ps", "ps2", "psc", "psc2", "pdf"}))) - have_ghostscript = ! isempty (__ghostscript_binary__ ()); - if (have_ghostscript) - file_exists = ((numel (dir (arg_st.name)) == 1) - && (! isdir (arg_st.name))); - if (! file_exists) - arg_st.append_to_file = false; - endif - else - arg_st.append_to_file = false; - warning ("print.m: appended output requires ghostscript to be installed"); - endif - else - warning ("print.m: appended output is not supported for device '%s'", - arg_st.devopt); - arg_st.append_to_file = false; - endif - endif - - if (! isempty (arg_st.printer) || isempty (arg_st.name)) - arg_st.send_to_printer = true; - endif - - if (any (strcmp (arg_st.devopt, {"ps", "ps2", "psc", "psc2", "pdf"}))) - arg_st.formatted_for_printing = true; - endif - - aliases = gs_aliases (); - if (any (strcmp (arg_st.devopt, fieldnames (aliases)))) - arg_st.devopt = aliases.(arg_st.devopt); - endif - - ## FIXME - eps2 & epsc2 needs to be handled - if (strcmp (arg_st.devopt, "pswrite")) - arg_st.ghostscript.level = 1; - elseif (strcmp (arg_st.devopt, "ps2write")) - arg_st.ghostscript.level = 2; - endif - - if ((any (strcmp (arg_st.devopt, gs_device_list)) - && ! arg_st.formatted_for_printing) - || any (strcmp (arg_st.devopt, {"pswrite", "ps2write", "pdfwrite"}))) - ## Use ghostscript for graphic formats - arg_st.ghostscript.device = arg_st.devopt; - arg_st.ghostscript.output = arg_st.name; - arg_st.ghostscript.antialiasing = true; - if (arg_st.formatted_for_printing) - arg_st.ghostscript.epscrop = ! arg_st.loose; - else - ## pstoedit throws errors if the EPS file isn't cropped - arg_st.ghostscript.epscrop = true; - endif - elseif (all (! strcmp (arg_st.devopt, dev_list))) - ## Assume we are formating output for a printer - arg_st.formatted_for_printing = true; - arg_st.ghostscript.device = arg_st.devopt; - arg_st.ghostscript.output = arg_st.name; - arg_st.ghostscript.antialiasing = false; - arg_st.ghostscript.epscrop = ! arg_st.loose; - endif - - if (isempty (arg_st.canvas_size)) - if (isfigure (arg_st.figure)) - [arg_st.ghostscript.papersize, paperposition] = ... - gs_papersize (arg_st.figure, arg_st.orientation); - else - ## allows tests to be run - arg_st.ghostscript.papersize = "letter"; - paperposition = [0.25, 2.50, 8.00, 6.00] * 72; - endif - arg_st.canvas_size = paperposition(3:4); - if (strcmp (__graphics_toolkit__, "gnuplot") && ! arg_st.ghostscript.epscrop) - arg_st.ghostscript.pageoffset = paperposition(1:2) - 50; - else - arg_st.ghostscript.pageoffset = paperposition(1:2); - endif - else - ## Convert canvas size to points from pixles. - arg_st.canvas_size = arg_st.canvas_size * 72 / arg_st.ghostscript.resolution; - arg_st.ghostscript.papersize = arg_st.canvas_size; - arg_st.ghostscript.epscrop = true; - arg_st.ghostscript.pageoffset = [0, 0]; - endif - - if (arg_st.formatted_for_printing) - arg_st.ghostscript.resolution = []; - else - arg_st.ghostscript.papersize = ""; - arg_st.ghostscript.pageoffset = [0, 0]; - endif - - if (warn_on_missing_binary) - if (isempty (arg_st.ghostscript.binary)) - warning ("print:missing_gs", "print.m: Ghostscript binary is not available.\nOnly eps output is available."); - else - if (isempty (arg_st.epstool_binary)) - warning ("print:missing_epstool", "print.m: epstool binary is not available.\nSome output formats are not available."); - endif - if (isempty (arg_st.fig2dev_binary)) - warning ("print:missing_fig2dev", "print.m: fig2dev binary is not available.\nSome output formats are not available."); - endif - if (isempty (arg_st.pstoedit_binary)) - warning ("print:missing_pstoedit", "print.m: pstoedit binary is not available.\nSome output formats are not available."); - endif - endif - warn_on_missing_binary = false; - endif - -endfunction - -%!test -%! opts = __print_parse_opts__ (); -%! assert (opts.devopt, "pswrite"); -%! assert (opts.use_color, 1); -%! assert (opts.send_to_printer, true); -%! assert (opts.canvas_size, [576, 432]); -%! assert (opts.ghostscript.device, "pswrite") - -%!test -%! opts = __print_parse_opts__ ("test.pdf", "-S640,480"); -%! assert (opts.canvas_size, [307.2, 230.4], 0.1); - -%!test -%! opts = __print_parse_opts__ ("-dpsc", "-append", "-loose"); -%! assert (opts.devopt, "pswrite"); -%! assert (opts.send_to_printer, true); -%! assert (opts.use_color, 1); -%! assert (opts.append_to_file, false); -%! assert (opts.ghostscript.device, "pswrite") -%! assert (opts.ghostscript.epscrop, false); - -%!test -%! opts = __print_parse_opts__ ("-deps", "-tight"); -%! assert (opts.tight_flag, true); -%! assert (opts.send_to_printer, true); -%! assert (opts.use_color, -1); -%! assert (opts.ghostscript.device, "") - -%!test -%! opts = __print_parse_opts__ ("-djpg", "foobar", "-mono", "-loose"); -%! assert (opts.devopt, "jpeg") -%! assert (opts.name, "foobar.jpg") -%! assert (opts.ghostscript.device, "jpeg") -%! assert (opts.ghostscript.epscrop, true); -%! assert (opts.ghostscript.papersize, ""); -%! assert (opts.ghostscript.pageoffset, [0, 0]); -%! assert (opts.send_to_printer, false); -%! assert (opts.printer, ""); -%! assert (opts.use_color, -1); - -%!test -%! opts = __print_parse_opts__ ("-ddeskjet", "foobar", "-mono", "-Pmyprinter"); -%! assert (opts.ghostscript.output, "foobar.deskjet") -%! assert (opts.ghostscript.device, "deskjet") -%! assert (opts.devopt, "deskjet") -%! assert (opts.send_to_printer, true); -%! assert (opts.printer, "-Pmyprinter"); -%! assert (opts.use_color, -1); - -%!test -%! opts = __print_parse_opts__ ("-f5", "-dljet3"); -%! assert (opts.ghostscript.device, "ljet3") -%! assert (strfind (opts.ghostscript.output, ".ljet3")) -%! assert (opts.devopt, "ljet3") -%! assert (opts.send_to_printer, true); -%! assert (opts.figure, 5) - -function cmd = __quote_path__ (cmd) - if (any (cmd == " ") && ! (cmd(1) == """" && cmd(end) == """")) - cmd = strcat ("""", strrep (cmd, """", """"""), """"); - endif -endfunction - -function gs = __ghostscript_binary__ () - - persistent ghostscript_binary = "" - persistent warn_on_no_ghostscript = true - persistent warn_on_bad_gsc = true - - if (isempty (ghostscript_binary)) - GSC = getenv ("GSC"); - if (exist (GSC, "file") - || (! isempty (GSC) && file_in_path (getenv ("PATH"), GSC))) - gs_binaries = {GSC}; - elseif (! isempty (GSC) && warn_on_bad_gsc) - warning ("print:badgscenv", - "print.m: GSC environment variable not set properly"); - warn_on_bad_gsc = false; - gs_binaries = {}; - else - gs_binaries = {}; - endif - if (isunix ()) - ## Unix - Includes Mac OSX and Cygwin. - gs_binaries = horzcat (gs_binaries, {"gs", "gs.exe"}); - else - ## pc - Includes Win32 and mingw. - gs_binaries = horzcat (gs_binaries, {"gs.exe", "gswin32c.exe"}); - endif - n = 0; - while (n < numel (gs_binaries) && isempty (ghostscript_binary)) - n = n + 1; - ghostscript_binary = file_in_path (getenv ("PATH"), gs_binaries{n}); - endwhile - if (warn_on_no_ghostscript && isempty (ghostscript_binary)) - warning ("print:noghostscript", - "print.m: ghostscript not found in PATH"); - warn_on_no_ghostscript = false; - endif - endif - - gs = ghostscript_binary; - -endfunction - -function bin = __find_binary__ (binary) - - persistent data = struct () - - if (! isfield (data, binary)) - ## Reinitialize when `user_binaries' is present. - data.(binary).bin = ""; - data.(binary).warn_on_absence = false; - endif - - if (isempty (data.(binary).bin)) - if (isunix ()) - ## Unix - Includes Mac OSX and Cygwin. - binaries = strcat (binary, {"", ".exe"}); - else - ## pc - Includes Win32 and mingw. - binaries = strcat (binary, {".exe"}); - endif - n = 0; - while (n < numel (binaries) && isempty (data.(binary).bin)) - n = n + 1; - data.(binary).bin = file_in_path (getenv ("PATH"), binaries{n}); - endwhile - if (isempty (data.(binary).bin) && data.(binary).warn_on_absence) - warning (sprintf ("print:no%s", binary), - "print.m: '%s' not found in PATH", binary); - data.(binary).warn_on_absence = false; - endif - endif - - bin = data.(binary).bin; - -endfunction - -function [papersize, paperposition] = gs_papersize (hfig, paperorientation) - persistent papertypes papersizes - - if (isempty (papertypes)) - papertypes = {"usletter", "uslegal", "a0", "a1", ... - "a2", "a3", "a4", "a5", ... - "b0", "b1", "b2", "b3", ... - "b4", "b5", "arch-a", "arch-b", ... - "arch-c", "arch-d", "arch-e", "a", ... - "b", "c", "d", "e", ... - "tabloid"}; - papersizes = [ 8.5, 11.0; 8.5, 14.0; 33.1, 46.8; 23.4, 33.1; - 16.5, 23.4; 11.7, 16.5; 8.3, 11.7; 5.8, 8.3; - 39.4, 55.7; 27.8, 39.4; 19.7, 27.8; 13.9, 19.7; - 9.8, 13.9; 6.9, 9.8; 9.0, 12.0; 12.0, 18.0; - 18.0, 24.0; 24.0, 36.0; 36.0, 48.0; 8.5, 11.0; - 11.0, 17.0; 18.0, 24.0; 24.0, 36.0; 36.0, 48.0; - 11.0, 17.0] * 72; - endif - - papertype = get (hfig, "papertype"); - paperunits = get (hfig, "paperunits"); - paperposition = get (hfig, "paperposition"); - if (strcmp (papertype, "<custom>")) - papersize = get (hfig, "papersize"); - papersize = convert2points (papersize , paperunits); - else - papersize = papersizes (strcmp (papertypes, papertype), :); - endif - - if (strcmp (paperunits, "normalized")) - paperposition = paperposition .* papersize([1,2,1,2]); - else - paperposition = convert2points (paperposition, paperunits); - endif - - ## FIXME - This will be obsoleted by listeners for paper properties. - ## Papersize is tall when portrait,and wide when landscape. - if ((papersize(1) > papersize(2) && strcmpi (paperorientation, "portrait")) - || (papersize(1) < papersize(2) && strcmpi (paperorientation, "landscape"))) - papersize = papersize ([2,1]); - paperposition = paperposition([2,1,4,3]); - endif - - if ((! strcmp (papertype, "<custom>")) && (strcmp (paperorientation, "portrait"))) - ## For portrait use the ghostscript name - papersize = papertype; - papersize(papersize=="-") = ""; - papersize = strrep (papersize, "us", ""); - switch (papersize) - case "a" - papersize = "letter"; - case {"b", "tabloid"} - papersize = "11x17"; - case {"c", "d", "e"} - papersize = strcat ("arch", papersize); - endswitch - if (strncmp (papersize, "arch", 4)) - papersize(end) = upper (papersize(end)); - endif - endif - -endfunction - -function value = convert2points (value, units) - switch (units) - case "inches" - value = value * 72; - case "centimeters" - value = value * 72 / 25.4; - case "normalized" - error ("print:customnormalized", - "print.m: papersize=='<custom>' and paperunits='normalized' may not be combined"); - endswitch -endfunction - -function device_list = gs_device_list (); - ## Graphics formats/languages, not priners. - device_list = {"bmp16"; "bmp16m"; "bmp256"; "bmp32b"; "bmpgray"; ... - "epswrite"; "jpeg"; "jpegcymk"; "jpeggray"; "pbm"; ... - "pbmraw"; "pcx16"; "pcx24b"; "pcx256"; "pcx2up"; ... - "pcxcmyk"; "pcxgray"; "pcxmono"; "pdfwrite"; "pgm"; ... - "pgmraw"; "pgnm"; "pgnmraw"; "png16"; "png16m"; ... - "png256"; "png48"; "pngalpha"; "pnggray"; "pngmono"; ... - "pnm"; "pnmraw"; "ppm"; "ppmraw"; "ps2write"; ... - "pswrite"; "tiff12nc"; "tiff24nc"; "tiff32nc"; ... - "tiffcrle"; "tiffg3"; "tiffg32d"; "tiffg4"; ... - "tiffgray"; "tifflzw"; "tiffpack"; "tiffsep"}; -endfunction - -function aliases = gs_aliases (); - ## Aliases for other devices: "bmp", "png", "tiff", "tiffn", "pdf", - ## "ps", "ps2", "psc", "psc2" - ## - ## eps, epsc, eps2, epsc2 are not included here because those are - ## are generated by the graphics toolkit. - aliases.bmp = "bmp32b"; - aliases.pdf = "pdfwrite"; - aliases.png = "png16m"; - aliases.ps = "pswrite"; - aliases.ps2 = "ps2write"; - aliases.psc = "pswrite"; - aliases.psc2 = "ps2write"; - aliases.tiff = "tiff24nc"; - aliases.tiffn = "tiff24nc"; -endfunction -
--- a/scripts/plot/axis.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/axis.m Fri Aug 12 14:16:34 2011 -0400 @@ -323,10 +323,10 @@ data(data<=0) = NaN; end if (iscell (data)) - data = data (find (! cellfun (@isempty, data))); + data = data (find (! cellfun ("isempty", data))); if (! isempty (data)) - lims_min = min (cellfun (@min, cellfun (@min, data, 'uniformoutput', false)(:))); - lims_max = max (cellfun (@max, cellfun (@max, data, 'uniformoutput', false)(:))); + lims_min = min (cellfun ("min", cellfun ("min", data, 'uniformoutput', false)(:))); + lims_max = max (cellfun ("max", cellfun ("max", data, 'uniformoutput', false)(:))); lims = [lims_min, lims_max]; else lims = [0, 1];
--- a/scripts/plot/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -20,38 +20,38 @@ plot/private/__errplot__.m \ plot/private/__ezplot__.m \ plot/private/__fltk_file_filter__.m \ - plot/private/__ghostscript__.m \ + plot/private/__fltk_ginput__.m \ + plot/private/__fltk_print__.m \ plot/private/__getlegenddata__.m \ + plot/private/__ghostscript__.m \ + plot/private/__gnuplot_get_var__.m \ + plot/private/__gnuplot_ginput__.m \ + plot/private/__gnuplot_has_feature__.m \ plot/private/__gnuplot_has_terminal__.m\ + plot/private/__gnuplot_open_stream__.m \ + plot/private/__gnuplot_print__.m \ + plot/private/__gnuplot_version__.m \ + plot/private/__go_draw_axes__.m \ + plot/private/__go_draw_figure__.m \ plot/private/__interp_cube__.m \ plot/private/__line__.m \ + plot/private/__marching_cube__.m \ + plot/private/__next_line_color__.m \ + plot/private/__next_line_style__.m \ plot/private/__patch__.m \ plot/private/__pie__.m \ plot/private/__plt__.m \ plot/private/__pltopt__.m \ + plot/private/__print_parse_opts__.m \ plot/private/__quiver__.m \ plot/private/__scatter__.m \ plot/private/__stem__.m \ plot/private/__tight_eps_bbox__.m plot_FCN_FILES = \ - plot/__fltk_ginput__.m \ - plot/__fltk_print__.m \ plot/__gnuplot_drawnow__.m \ - plot/__gnuplot_get_var__.m \ - plot/__gnuplot_ginput__.m \ - plot/__gnuplot_has_feature__.m \ - plot/__gnuplot_open_stream__.m \ - plot/__gnuplot_print__.m \ - plot/__gnuplot_version__.m \ plot/__go_close_all__.m \ - plot/__go_draw_axes__.m \ - plot/__go_draw_figure__.m \ - plot/__marching_cube__.m \ - plot/__next_line_color__.m \ - plot/__next_line_style__.m \ plot/__plt_get_axis_arg__.m \ - plot/__print_parse_opts__.m \ plot/allchild.m \ plot/ancestor.m \ plot/area.m \ @@ -171,6 +171,9 @@ plot/surfnorm.m \ plot/text.m \ plot/title.m \ + plot/trimesh.m \ + plot/triplot.m \ + plot/trisurf.m \ plot/uigetdir.m \ plot/uigetfile.m \ plot/uimenu.m \
--- a/scripts/plot/pareto.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/pareto.m Fri Aug 12 14:16:34 2011 -0400 @@ -66,11 +66,11 @@ if (ischar (y)) y = cellstr (y); else - y = cellfun (@num2str, num2cell (y), "uniformoutput", false); + y = cellfun ("num2str", num2cell (y), "uniformoutput", false); endif endif else - y = cellfun (@int2str, num2cell (1 : numel(x)), + y = cellfun ("int2str", num2cell (1 : numel(x)), "uniformoutput", false); endif
--- a/scripts/plot/pcolor.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/pcolor.m Fri Aug 12 14:16:34 2011 -0400 @@ -80,3 +80,14 @@ endif endfunction + +%!demo +%! clf +%! [~,~,Z]=peaks; +%! pcolor(Z); + +%!demo +%! [X,Y,Z]=sombrero; +%! [Fx,Fy] = gradient(Z); +%! pcolor(X,Y,Fx+Fy); +%! shading interp;
--- a/scripts/plot/plotyy.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/plotyy.m Fri Aug 12 14:16:34 2011 -0400 @@ -78,7 +78,7 @@ ca = get (f, "currentaxes"); if (isempty (ca)) ax = []; - elseif (strcmp (get (ca, "tag"), "plotyy")); + elseif (strcmp (get (ca, "tag"), "plotyy")) ax = get (ca, "__plotyy_axes__"); else ax = ca; @@ -113,8 +113,6 @@ endif end_unwind_protect - set (ax, "activepositionproperty", "position"); - if (nargout > 0) Ax = ax; H1 = h1; @@ -162,10 +160,24 @@ colors = get (ax(1), "colororder"); set (ax(2), "colororder", [colors(2:end,:); colors(1,:)]); + if (strcmp (get (ax(1), "autopos_tag"), "subplot")) + set (ax(2), "autopos_tag", "subplot"); + else + set (ax, "activepositionproperty", "position"); + endif + h2 = feval (fun2, x2, y2); set (ax(2), "yaxislocation", "right"); set (ax(2), "ycolor", getcolor (h2(1))); - set (ax(2), "position", get (ax(1), "position")); + + + if (strcmp (get(ax(1), "activepositionproperty"), "position")) + set (ax(2), "position", get (ax(1), "position")); + else + set (ax(2), "outerposition", get (ax(1), "outerposition")); + set (ax(2), "looseinset", get (ax(1), "looseinset")); + endif + set (ax(2), "xlim", xlim); set (ax(2), "color", "none"); set (ax(2), "box", "off"); @@ -184,6 +196,10 @@ addlistener (ax(1), "position", {@update_position, ax(2)}); addlistener (ax(2), "position", {@update_position, ax(1)}); + addlistener (ax(1), "outerposition", {@update_position, ax(2)}); + addlistener (ax(2), "outerposition", {@update_position, ax(1)}); + addlistener (ax(1), "looseinset", {@update_position, ax(2)}); + addlistener (ax(2), "looseinset", {@update_position, ax(1)}); addlistener (ax(1), "view", {@update_position, ax(2)}); addlistener (ax(2), "view", {@update_position, ax(1)}); addlistener (ax(1), "plotboxaspectratio", {@update_position, ax(2)}); @@ -257,17 +273,27 @@ if (! recursion) unwind_protect recursion = true; - position = get (h, "position"); view = get (h, "view"); - plotboxaspectratio = get (h, "plotboxaspectratio"); - plotboxaspectratiomode = get (h, "plotboxaspectratiomode"); - oldposition = get (ax2, "position"); oldview = get (ax2, "view"); + plotboxaspectratio = get (h, "plotboxaspectratio"); oldplotboxaspectratio = get (ax2, "plotboxaspectratio"); + plotboxaspectratiomode = get (h, "plotboxaspectratiomode"); oldplotboxaspectratiomode = get (ax2, "plotboxaspectratiomode"); - if (! (isequal (position, oldposition) && isequal (view, oldview))) - set (ax2, "position", position, "view", view); + + if (strcmp (get(h, "activepositionproperty"), "position")) + position = get (h, "position"); + oldposition = get (ax2, "position"); + if (! (isequal (position, oldposition) && isequal (view, oldview))) + set (ax2, "position", position, "view", view); + endif + else + outerposition = get (h, "outerposition"); + oldouterposition = get (ax2, "outerposition"); + if (! (isequal (outerposition, oldouterposition) && isequal (view, oldview))) + set (ax2, "outerposition", outerposition, "view", view); + endif endif + if (! (isequal (plotboxaspectratio, oldplotboxaspectratio) && isequal (plotboxaspectratiomode, oldplotboxaspectratiomode))) set (ax2, "plotboxaspectratio", plotboxaspectratio);
--- a/scripts/plot/polar.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/polar.m Fri Aug 12 14:16:34 2011 -0400 @@ -211,3 +211,15 @@ endif endfunction + + +%!demo +%! theta = linspace (0, 2*pi, 1000); +%! rho = sin (7*theta); +%! polar (theta, rho); + +%!demo +%! theta = linspace (0, 10*pi, 1000); +%! rho = sin (5/4*theta); +%! polar (theta, rho); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__fltk_ginput__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,105 @@ +## Copyright (C) 2010-2011 Shai Ayal +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __fltk_ginput__ (@var{f}, @var{n}) +## Undocumented internal function. +## @end deftypefn + +## This is ginput.m implementation for fltk. + +## FIXME -- Key presses cannot toggle menu items nor hotkey functionality +## (grid, autoscale) during ginput! + +function [x, y, button] = __fltk_ginput__ (f, n = -1) + + if (isempty (get (f, "currentaxes"))) + error ("ginput: must have at least one axes"); + endif + + x = y = button = []; + ginput_aggregator (0, 0, 0, 0); + + unwind_protect + + orig_windowbuttondownfcn = get (f, "windowbuttondownfcn"); + set (f, "windowbuttondownfcn", @ginput_windowbuttondownfcn); + + orig_ginput_keypressfcn = get (f, "keypressfcn"); + set (f, "keypressfcn", @ginput_keypressfcn); + + while (true) + __fltk_redraw__ (); + + ## Release CPU. + sleep (0.01); + + [x, y, n0, button] = ginput_aggregator (-1, 0, 0, 0); + if (n0 == n || n0 < 0) + break; + endif + endwhile + + unwind_protect_cleanup + set (f, "windowbuttondownfcn", orig_windowbuttondownfcn); + set (f, "keypressfcn", orig_ginput_keypressfcn); + end_unwind_protect + +endfunction + +function [x, y, n, button] = ginput_aggregator (mode, xn, yn, btn) + persistent x y n button; + + if (mode == 0) + ## Initialize. + x = []; + y = []; + button = []; + n = 0; + elseif (mode == 1) + ## Accept mouse button or key press. + x = [x; xn]; + y = [y; yn]; + button = [button; btn]; + n += 1; + elseif (mode == 2) + ## The end due to Enter. + n = -1; + endif +endfunction + +function ginput_windowbuttondownfcn (src, data) + point = get (get (src,"currentaxes"), "currentpoint"); + ## FIXME -- How to get the actual mouse button pressed (1,2,3) into + ## "button"? + button = 1; + ginput_aggregator (1, point(1,1), point(2,1), button); +endfunction + +function ginput_keypressfcn (src, evt) + point = get (get (src, "currentaxes"), "currentpoint"); + ## FIXME -- use evt.Key or evt.Character? + key = evt.Key; + if (key == 10) + ## Enter key. + ginput_aggregator (2, point(1,1), point(2,1), key); + else + ginput_aggregator (1, point(1,1), point(2,1), key); + endif +endfunction +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__fltk_print__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,161 @@ +## Copyright (C) 2010-2011 Shai Ayal +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} __fltk_print__ (@var{@dots{}}) +## Undocumented internal function. +## @end deftypefn + +function opts = __fltk_print__ (opts) + + dos_shell = (ispc () && ! isunix ()); + + figure (opts.figure); + drawnow ("expose"); + __fltk_redraw__ (); + + if (! isempty (opts.fig2dev_binary)) + ## fig2dev is prefered for conversion to emf + fig2dev_devices = {"pstex", "mf", "emf"}; + else + fig2dev_devices = {"pstex", "mf"}; + endif + + gl2ps_device = {}; + pipeline = {}; + switch (lower (opts.devopt)) + case {"eps", "eps2", "epsc", "epsc2"} + ## format GL2PS_EPS + gl2ps_device = {"eps"}; + ## FIXME - use epstool to tighten bbox and provide preview. + pipeline = {opts.epstool_cmd(opts, "-", opts.name)}; + case {"epslatex", "pslatex", "pdflatex", "epslatexstandalone", ... + "pslatexstandalone", "pdflatexstandalone"} + ## format GL2PS_TEX + n = find (opts.devopt == "l", 1); + suffix = opts.devopt(1:n-1); + dot = find (opts.name == ".", 1, "last"); + if ((! isempty (dot)) + && any (strcmpi (opts.name(dot:end), ... + {".eps", ".ps", ".pdf", ".tex", "."}))) + name = opts.name(1:dot-1); + if (dot < numel (opts.name) + && any (strcmpi (opts.name(dot+1:end), {"eps", "ps", "pdf"}))) + ## If user provides eps/ps/pdf suffix, use it. + suffix = opts.name(dot+1:end); + endif + elseif (dot == numel (opts.name)) + name = opts.name; + endif + gl2ps_device = {sprintf("%snotxt", lower (suffix))}; + gl2ps_device{2} = "tex"; + if (dos_shell) + ## FIXME - this will only work on MinGW with the MSYS shell + pipeline = {sprintf("cat > %s-inc.%s", name, suffix)}; + pipeline{2} = sprintf ("cat > %s.tex", name); + else + pipeline = {sprintf("cat > %s-inc.%s", name, suffix)}; + pipeline{2} = sprintf ("cat > %s.tex", name); + endif + case "tikz" + ## format GL2PS_PGF + gl2ps_device = {"pgf"}; + pipeline = {sprintf("cat > %s", opts.name)}; + case "svg" + ## format GL2PS_SVG + gl2ps_device = {"svg"}; + pipeline = {sprintf("cat > %s", opts.name)}; + case fig2dev_devices + cmd_pstoedit = opts.pstoedit_cmd (opts, "fig"); + cmd_fig2dev = opts.fig2dev_cmd (opts, opts.devopt); + if (strcmp (opts.devopt, "pstex")) + [~, ~, ext] = fileparts (opts.name); + if (any (strcmpi (ext, {".ps", ".tex", "."}))) + opts.name = opts.name(1:end-numel(ext)); + endif + opts.name = strcat (opts.name, ".ps"); + cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name); + gl2ps_device = {"eps"}; + pipeline = {cmd}; + cmd_fig2dev = opts.fig2dev_cmd (opts, "pstex_t"); + gl2ps_device{2} = "eps"; + pipeline{2} = sprintf ("%s | %s > %s", cmd_pstoedit, + cmd_fig2dev, strrep(opts.name, ".ps", ".tex")); + else + cmd = sprintf ("%s | %s > %s", cmd_pstoedit, cmd_fig2dev, opts.name); + gl2ps_device = {"eps"}; + pipeline = {cmd}; + endif + case "aifm" + cmd = opts.pstoedit_cmd (opts, "ps2ai"); + gl2ps_device = {"eps"}; + pipeline = {sprintf("%s > %s", cmd, opts.name)}; + case {"dxf", "emf", "fig", "hpgl"} + cmd = opts.pstoedit_cmd (opts); + gl2ps_device = {"eps"}; + pipeline = {sprintf("%s > %s", cmd, opts.name)}; + case {"corel", "gif"} + error ("print:unsupporteddevice", + "print.m: %s output is not available for the FLTK graphics toolkit", + upper (opts.devopt)); + case opts.ghostscript.device + opts.ghostscript.source = "-"; + opts.ghostscript.output = opts.name; + if (opts.send_to_printer) + opts.unlink(strcmp (opts.unlink, opts.ghostscript.output)) = []; + opts.ghostscript.output = "-"; + endif + [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript); + if (opts.send_to_printer || isempty (opts.name)) + cmd_lpr = opts.lpr_cmd (opts); + cmd = sprintf("%s | %s", cmd_gs, cmd_lpr); + else + cmd = sprintf("%s", cmd_gs); + endif + if (! isempty (cmd_cleanup)) + gl2ps_device = {"eps"}; + if (dos_shell) + pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)}; + else + pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)}; + endif + else + gl2ps_device = {"eps"}; + pipeline = {cmd}; + endif + otherwise + error (sprintf ("print:no%soutput", opts.devopt), + "print.m: %s output is not available for GL2PS output", + upper (opts.devopt)); + endswitch + + opts.pipeline = pipeline; + + for n = 1:numel(pipeline) + if (opts.debug) + fprintf ("fltk-pipeline: '%s'\n", pipeline{n}); + endif + drawnow (gl2ps_device{n}, strcat('|',pipeline{n})); + endfor + + if (! isempty (strfind (opts.devopt, "standalone"))) + opts.latex_standalone (opts); + endif + +endfunction +
--- a/scripts/plot/private/__ghostscript__.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/private/__ghostscript__.m Fri Aug 12 14:16:34 2011 -0400 @@ -44,7 +44,7 @@ cleanup_cmd = ""; args = varargin; - n = find (cellfun (@isstruct, args)); + n = find (cellfun ("isclass", args, "struct")); if (! isempty (n)) f = fieldnames (args{n}); for m = 1:numel(f)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__gnuplot_get_var__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,161 @@ +## Copyright (C) 2009-2011 Ben Abbott +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{value} =} __gnuplot_get_var__ (@var{h}, @var{name}, @var{fmt}) +## Undocumented internal function. +## @end deftypefn + +## Author: Ben Abbott <bpabbott@mac.com> +## Created: 2009-02-07 + +function gp_var_value = __gnuplot_get_var__ (h, gp_var_name, fmt) + + if (nargin == 0) + h = gcf (); + endif + if (nargin < 2) + print_usage (); + endif + if (nargin < 3) + fmt = ''; + endif + + if (numel (h) == 1 && isfigure (h)) + if (isempty (get (gcf, "__plot_stream__"))) + ostream = __gnuplot_open_stream__ (2, h); + else + ostream = get (h, "__plot_stream__"); + endif + else + ostream = h; + endif + if (numel (ostream) < 1) + error ("__gnuplot_get_var__: stream to gnuplot not open"); + elseif (ispc ()) + if (numel (ostream) == 1) + error ("__gnuplot_get_var__: Need mkfifo that is not implemented under Windows"); + endif + use_mkfifo = false; + istream = ostream(2); + ostream = ostream(1); + else + use_mkfifo = true; + ostream = ostream(1); + endif + + if (use_mkfifo) + gpin_name = tmpnam (); + + ## Mode: 6*8*8 == 0600 + [err, msg] = mkfifo (gpin_name, 6*8*8); + + if (err != 0) + error ("__gnuplot_get_var__: Can not make fifo (%s)", msg); + endif + endif + + gp_var_name = strtrim (gp_var_name); + n = min (strfind (gp_var_name, " "), strfind (gp_var_name, ",")) - 1; + if (isempty (n)) + n = numel (gp_var_name); + endif + + unwind_protect + + ## Notes: Variables may be undefined if user closes gnuplot by "q" + ## or Alt-F4. Further, this abrupt close also requires the leading + ## "\n" on the next line. + if (use_mkfifo) + fprintf (ostream, "\nset print \"%s\";\n", gpin_name); + fflush (ostream); + [gpin, err] = fopen (gpin_name, "r"); + if (err != 0) + ## Try a second time, and then give an error. + [gpin, err] = fopen (gpin_name, "r"); + endif + if (err != 0) + error ("__gnuplot_get_var__: can not open fifo"); + endif + gp_cmd = sprintf ("\nif (exists(\"%s\")) print %s; else print NaN\n", + gp_var_name(1:n), gp_var_name); + fputs (ostream, gp_cmd); + + ## Close output file, to force it to be flushed + fputs (ostream, "set print;\n"); + fflush (ostream); + + ## Now read from fifo. + reading = true; + str = {}; + while (reading) + str{end+1} = fgets (gpin); + if (isnumeric (str{end}) && (str{end} == -1)) + reading = false; + str = str(1:(end-1)); + endif + endwhile + str = strcat (str{:}); + fclose (gpin); + else + ## Direct gnuplot to print to <STDOUT> + fprintf (ostream, "set print \"-\";\n"); + fflush (ostream); + gp_cmd = sprintf ("\nif (exists(\"%s\")) print \"OCTAVE: \", %s; else print NaN\n", + gp_var_name(1:n), gp_var_name); + fputs (ostream, gp_cmd); + fflush (ostream); + ## Direct gnuplot to print to <STDERR> + fputs (ostream, "set print;\n"); + fflush (ostream); + + str = {}; + while (isempty (str)) + str = char (fread (istream)'); + if (isempty (str)) + sleep (0.05); + else + str = regexp (str, 'OCTAVE:.*', "match"); + str = str{end}(8:end); + endif + fclear (istream); + endwhile + endif + + ## Strip out EOLs and the continuation character "|" + str(str=="\n") = ""; + str(str=="\r") = ""; + n_continue = strfind (str, " \\ "); + if (! isempty (n_continue)) + str(n_continue+1) = ""; + endif + + if (isempty (fmt)) + gp_var_value = strtrim (str); + else + gp_var_value = sscanf (str, fmt); + endif + + unwind_protect_cleanup + if (use_mkfifo) + unlink (gpin_name); + endif + end_unwind_protect + +endfunction +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__gnuplot_ginput__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,154 @@ +## Copyright (C) 2004-2011 Petr Mikulik +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} __gnuplot_ginput__ (@var{f}, @var{n}) +## Undocumented internal function. +## @end deftypefn + +## This is ginput.m implementation for gnuplot and X11. +## It requires gnuplot 4.1 and later. + +## This file initially bore the copyright statement +## Petr Mikulik +## History: June 2006; August 2005; June 2004; April 2004 +## License: public domain + +function [x, y, button] = __gnuplot_ginput__ (f, n) + + ostream = get (f, "__plot_stream__"); + if (numel (ostream) < 1) + error ("ginput: stream to gnuplot not open"); + elseif (ispc ()) + if (numel (ostream) == 1) + error ("ginput: Need mkfifo that is not implemented under Windows"); + endif + use_mkfifo = false; + istream = ostream(2); + ostream = ostream(1); + else + use_mkfifo = true; + ostream = ostream(1); + endif + + if (compare_versions (__gnuplot_version__ (), "4.0", "<=")) + error ("ginput: version %s of gnuplot not supported", gnuplot_version ()); + endif + + if (nargin == 1) + x = zeros (100, 1); + y = zeros (100, 1); + button = zeros (100, 1); + else + x = zeros (n, 1); + y = zeros (n, 1); + button = zeros (n, 1); + endif + + if (use_mkfifo) + gpin_name = tmpnam (); + + ##Mode: 6*8*8 == 0600 + [err, msg] = mkfifo (gpin_name, 6*8*8); + + if (err != 0) + error ("ginput: Can not open fifo (%s)", msg); + endif + endif + + unwind_protect + + k = 0; + while (true) + k++; + + ## Notes: MOUSE_* can be undefined if user closes gnuplot by "q" + ## or Alt-F4. Further, this abrupt close also requires the leading + ## "\n" on the next line. + if (use_mkfifo) + fprintf (ostream, "set print \"%s\";\n", gpin_name); + fflush (ostream); + [gpin, err] = fopen (gpin_name, "r"); + if (err != 0) + error ("ginput: Can not open fifo (%s)", msg); + endif + fputs (ostream, "pause mouse any;\n\n"); + fputs (ostream, "\nif (exists(\"MOUSE_KEY\") && exists(\"MOUSE_X\")) print MOUSE_X, MOUSE_Y, MOUSE_KEY; else print \"0 0 -1\"\n"); + + ## Close output file, to force it to be flushed + fputs (ostream, "set print;\n"); + fflush (ostream); + + ## Now read from fifo. + [x(k), y(k), button(k), count] = fscanf (gpin, "%f %f %d", "C"); + fclose (gpin); + else + fprintf (ostream, "set print \"-\";\n"); + fflush (ostream); + fputs (ostream, "pause mouse any;\n\n"); + fputs (ostream, "\nif (exists(\"MOUSE_KEY\") && exists(\"MOUSE_X\")) print \"OCTAVE: \", MOUSE_X, MOUSE_Y, MOUSE_KEY; else print \"0 0 -1\"\n"); + + ## Close output file, to force it to be flushed + fputs (ostream, "set print;\n"); + fflush (ostream); + + str = {}; + while (isempty (str)) + str = char (fread (istream)'); + if (isempty (str)) + sleep (0.05); + else + str = regexp (str, 'OCTAVE:\s+[-+.\d]+\s+[-+.\d]+\s+\d*', 'match'); + endif + fclear (istream); + endwhile + [x(k), y(k), button(k), count] = sscanf (str{end}(8:end), "%f %f %d", "C"); + endif + + if ([x(k), y(k), button(k)] == [0, 0, -1]) + ## Mousing not active (no plot yet). + break; + endif + + if (nargin > 1) + ## Input argument n was given => stop when k == n. + if (k == n) + break; + endif + else + ## Input argument n not given => stop when hitting a return key. + ## if (button(k) == 0x0D || button(k) == 0x0A) + ## ## hit Return or Enter + if (button(k) == 0x0D) + ## hit Return + x(k:end) = []; + y(k:end) = []; + button(k:end) = []; + break; + endif + endif + endwhile + + unwind_protect_cleanup + if (use_mkfifo) + unlink (gpin_name); + endif + end_unwind_protect + +endfunction +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__gnuplot_has_feature__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,61 @@ +## Copyright (C) 2009-2011 Ben Abbott +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{has_feature} =} __gnuplot_has_feature__ (@var{feature}) +## Undocumented internal function. +## @end deftypefn + +## Author: Ben Abbott <bpabbott@mac.com> +## Created: 2009-01-27 + +function res = __gnuplot_has_feature__ (feature) + persistent features has_features + features = {"x11_figure_position", + "wxt_figure_size", + "transparent_patches", + "transparent_surface", + "epslatex_implies_eps_filesuffix", + "epslatexstandalone_terminal", + "screen_coordinates_for_{lrtb}margin", + "variable_GPVAL_TERMINALS", + "key_has_font_properties"}; + + if (isempty (has_features)) + try + gnuplot_version = __gnuplot_version__ (); + catch + ## Don't throw an error if gnuplot isn't installed + gnuplot_version = "0.0.0"; + end_try_catch + versions = {"4.2.5", "4.4", "4.4", "4.4", "4.2", "4.2", "4.4", "4.4", "4.4"}; + operators = {">=", ">=", ">=", ">=", ">=", ">=", ">=", ">=", ">="}; + have_features = logical (zeros (size (features))); + for n = 1 : numel (have_features) + has_features(n) = compare_versions (gnuplot_version, versions{n}, operators{n}); + endfor + endif + + n = find (strcmpi (feature, features)); + if (isempty (n)) + res = NaN; + else + res = has_features(n); + endif +endfunction +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__gnuplot_open_stream__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,45 @@ +## Copyright (C) 2009-2011 Ben Abbott +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{stream} =} __gnuplot_open_stream__ (@var{npipes}, @var{h}) +## Undocumented internal function. +## @end deftypefn + +## Author: Ben Abbott <bpabbott@mac.com> +## Created: 2009-04-11 + +function plot_stream = __gnuplot_open_stream__ (npipes, h) + [prog, args] = gnuplot_binary (); + if (npipes > 1) + [plot_stream(1), plot_stream(2), pid] = popen2 (prog, args{:}); + if (pid < 0) + error ("__gnuplot_open_stream__: failed to open connection to gnuplot"); + else + plot_stream(3) = pid; + endif + else + plot_stream = popen (sprintf ("%s ", prog, args{:}), "w"); + if (plot_stream < 0) + error ("__gnuplot_open_stream__: failed to open connection to gnuplot"); + endif + endif + if (nargin > 1) + set (h, "__plot_stream__", plot_stream); + endif +endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__gnuplot_print__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,300 @@ +## Copyright (C) 1999-2011 Daniel Heiserer +## Copyright (C) 2001 Laurent Mazet +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} __gnuplot_print__ (@var{@dots{}}) +## Undocumented internal function. +## @end deftypefn + +## Author: Daniel Heiserer <Daniel.heiserer@physik.tu-muenchen.de> +## Adapted-By: jwe + +function opts = __gnuplot_print__ (opts) + + dos_shell = (ispc () && ! isunix ()); + + if (isempty (opts.fontsize)) + ## If no fontsize, determine the nominal axes fontsize. + defaultfontsize = get (0, "defaultaxesfontsize"); + axesfontsize = get (findobj (opts.figure, "type", "axes"), "fontsize"); + if (iscell (axesfontsize)) + axesfontsize = round (median (cell2mat (axesfontsize))); + endif + if (isempty (axesfontsize)) + opts.fontsize = defaultfontsize; + else + opts.fontsize = axesfontsize; + endif + endif + ## The axes-label and tick-label spacing is determined by + ## the font spec given in "set terminal ..." + gp_opts = font_spec (opts); + + pipeline = ""; + + switch (lower (opts.devopt)) + case {"eps", "eps2", "epsc", "epsc2"} + if (any (strcmp (opts.devopt, {"eps", "epsc"}))) + gp_opts = sprintf ("%s level1", gp_opts); + endif + if (opts.tight_flag || ! isempty (opts.preview)) + tmp_file = strcat (tmpnam (), ".eps"); + eps_drawnow (opts, tmp_file, gp_opts); + if (dos_shell) + cleanup = sprintf (" & del %s", strrep (tmp_file, '/', '\')); + else + cleanup = sprintf (" ; rm %s", tmp_file); + endif + pipeline = {sprintf("%s %s", + opts.epstool_cmd (opts, tmp_file, opts.name), + cleanup)}; + else + eps_drawnow (opts, opts.name, gp_opts); + endif + case {"epslatex", "pslatex", "pstex", "epslatexstandalone"} + dot = find (opts.name == ".", 1, "last"); + if ((! isempty (dot)) + && any (strcmpi (opts.name(dot:end), + {".eps", ".ps", ".pdf", ".tex", "."}))) + name = opts.name(1:dot-1); + endif + if (strfind (opts.devopt, "standalone")) + term = sprintf ("%s ", + strrep (opts.devopt, "standalone", " standalone")); + else + term = sprintf ("%s ", opts.devopt); + endif + if (__gnuplot_has_feature__ ("epslatex_implies_eps_filesuffix")) + suffix = "tex"; + else + %% Gnuplot 4.0 wants a ".eps" suffix. + suffix = "eps"; + endif + local_drawnow (sprintf ("%s %s", term, gp_opts), + strcat (name, ".", suffix), opts); + case "tikz" + if (__gnuplot_has_terminal__ ("tikz")) + local_drawnow (sprintf ("lua tikz %s", gp_opts), opts.name, opts); + else + error (sprintf ("print:no%soutput", opts.devopt), + "print.m: '%s' output is not available for gnuplot-%s", + upper (opts.devopt), __gnuplot_version__ ()); + endif + case "svg" + local_drawnow (sprintf ("svg dynamic %s", gp_opts), opts.name, opts); + case {"aifm", "corel", "eepic", "emf", "fig"} + local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts); + case {"pdfcairo", "pngcairo"} + if (__gnuplot_has_terminal__ (opts.devopt)) + local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts); + else + error (sprintf ("print:no%soutput", opts.devopt), + "print.m: '%s' output is not available for gnuplot-%s", + upper (opts.devopt), __gnuplot_version__ ()); + endif + case {"canvas", "dxf", "hpgl", "mf", "gif", "pstricks", "texdraw"} + local_drawnow (sprintf ("%s %s", opts.devopt, gp_opts), opts.name, opts); + case opts.ghostscript.device + gp_opts = font_spec (opts, "devopt", "eps"); + opts.ghostscript.output = opts.name; + opts.ghostscript.source = strcat (tmpnam (), ".eps"); + eps_drawnow (opts, opts.ghostscript.source, gp_opts); + [cmd_gs, cmd_cleanup] = __ghostscript__ (opts.ghostscript); + if (opts.send_to_printer || isempty (opts.name)) + cmd_lpr = opts.lpr_cmd (opts); + cmd = sprintf ("%s | %s", cmd_gs, cmd_lpr); + else + cmd = sprintf ("%s", cmd_gs); + endif + if (dos_shell) + cmd = sprintf ("%s & del %s", cmd, strrep (opts.ghostscript.source, '/', '\')); + else + cmd = sprintf ("%s ; rm %s", cmd, opts.ghostscript.source); + endif + if (! isempty (cmd_cleanup)) + if (dos_shell) + pipeline = {sprintf("%s & %s", cmd, cmd_cleanup)}; + else + pipeline = {sprintf("%s ; %s", cmd, cmd_cleanup)}; + endif + else + pipeline = {cmd}; + endif + otherwise + error (sprintf ("print:no%soutput", opts.devopt), + "print.m: %s output is not available for the Gnuplot graphics toolkit", + upper (opts.devopt)); + endswitch + + + opts.pipeline = pipeline; + + for n = 1:numel(pipeline) + if (opts.debug) + fprintf ("gnuplot-pipeline: '%s'\n", pipeline{n}); + endif + [status, output] = system (pipeline{n}); + if (status) + fprintf ("%s\n%s\n%s\n", + "---------- output begin ----------", + output, + "----------- output end -----------"); + error ("gnuplot:failedpipe", "print: failed to print"); + endif + endfor + +endfunction + +function eps_drawnow (opts, epsfile, gp_opts) + [h, fontsize] = get_figure_text_objs (opts); + unwind_protect + for n = 1:numel(h) + set (h(n), "fontsize", 2 * fontsize{n}); + endfor + local_drawnow (sprintf ("postscript eps %s", gp_opts), epsfile, opts); + unwind_protect_cleanup + for n = 1:numel(h) + set (h(n), "fontsize", fontsize{n}); + endfor + end_unwind_protect +endfunction + +function local_drawnow (term, file, opts) + if (opts.use_color < 0) + mono = true; + else + mono = false; + endif + figure (opts.figure); + if (isempty (opts.debug_file) || ! opts.debug) + drawnow (term, file, mono); + else + drawnow (term, file, mono, opts.debug_file); + endif +endfunction + +function f = font_spec (opts, varargin) + for n = 1:2:numel(varargin) + opts.(varargin{n}) = varargin{n+1}; + endfor + f = ""; + switch (opts.devopt) + case "cgm" + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + f = sprintf ("font ""%s,%d""", opts.font, opts.fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("font ""%s""", opts.font); + elseif (! isempty (opts.fontsize)) + f = sprintf ("%d", opts.fontsize); + endif + case {"eps", "eps2", "epsc", "epsc2"} + ## Gnuplot renders fonts as half their specification, which + ## results in a tight spacing for the axes-labels and tick-labels. + ## Compensate for the half scale. This will produce the proper + ## spacing for the requested fontsize. + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + f = sprintf ("font ""%s,%d""", opts.font, 2 * opts.fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("font ""%s""", opts.font); + elseif (! isempty (opts.fontsize)) + f = sprintf ("%d", 2 * opts.fontsize); + endif + case "svg" + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + fontsize = round (opts.fontsize * 0.75); + f = sprintf ("fname ""%s"" fsize %d", opts.font, fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("fname ""%s""", opts.font); + elseif (! isempty (opts.fontsize)) + fontsize = round (opts.fontsize * 0.75); + f = sprintf ("%s fsize %d", f, fontsize); + endif + case "pdf" + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + f = sprintf ("font ""%s,%d""", opts.font, opts.fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("font ""%s""", opts.font); + elseif (! isempty (opts.fontsize)) + f = sprintf ("fsize %d", f, opts.fontsize); + endif + case {"pdfcairo", "pngcairo"} + if (! isempty (opts.font)) + f = sprintf ("font ""%s""", opts.font); + endif + case {"epslatex", "epslatexstandalone"} + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + f = sprintf ("font ""%s,%d""", opts.font, opts.fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("font ""%s""", opts.font); + elseif (! isempty (opts.fontsize)) + f = sprintf ("%d", opts.fontsize); + endif + case "pslatex" + if (! isempty (opts.fontsize)) + f = sprintf ("%d", opts.fontsize); + endif + case {"gif", "jpeg", "png"} + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + f = sprintf ("font ""%s ,%d""", opts.font, opts.fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("font ""%s""", opts.font); + elseif (! isempty (opts.fontsize)) + f = sprintf ("font ""%d""", opts.fontsize); + endif + case "emf" + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + f = sprintf ("""%s"" %d", opts.font, opts.fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("""%s""", opts.font); + elseif (! isempty (opts.fontsize)) + f = sprintf ("%d", opts.fontsize); + endif + case "canvas" + if (! isempty (opts.fontsize)) + f = sprintf ("fsize %d", opts.fontsize); + endif + case {"aifm", "corel"} + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + f = sprintf ("%s %d", opts.font, opts.fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("%s", opts.font); + elseif (! isempty (opts.fontsize)) + f = sprintf ("%d", opts.fontsize); + endif + case "fig" + if (! isempty (opts.font) && ! isempty (opts.fontsize)) + f = sprintf ("font %s fontsize %d", opts.font, opts.fontsize); + elseif (! isempty (opts.font)) + f = sprintf ("font %s", opts.font); + elseif (! isempty (opts.fontsize)) + f = sprintf ("fontsize %d", opts.fontsize); + endif + endswitch +endfunction + +function [h, fontsize] = get_figure_text_objs (opts) + h = findall (opts.figure, "-property", "fontsize"); + fontsize = get (h, "fontsize"); + switch (numel (fontsize)) + case 0 + fontsize = {}; + case 1 + fontsize = {fontsize}; + endswitch +endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__gnuplot_version__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,51 @@ +## Copyright (C) 2006-2011 Daniel Sebald +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{version} =} __gnuplot_version__ () +## Undocumented internal function. +## @end deftypefn + +## Return the version of gnuplot we are using. Note that we do not +## attempt to handle the case of the user switching to different +## versions of gnuplot during the same session. + +function version = __gnuplot_version__ () + + persistent __version__ = ""; + + if (isempty (__version__)) + [status, output] = system (sprintf ("\"%s\" --version", gnuplot_binary ())); + if (status != 0) + ## This message ends in a newline so that the traceback messages + ## are skipped and people might actually see the message, read it, + ## comprehend it, actually take the advice it gives, and stop + ## asking us why plotting fails when gnuplot is not found. + error ("you must have gnuplot installed to display graphics; if you have gnuplot installed in a non-standard location, see the 'gnuplot_binary' function\n"); + endif + output = strrep (output, "gnuplot", ""); + output = strrep (output, "patchlevel", "."); + output = strrep (output, "\n", ""); + output = strrep (output, "\r", ""); + __version__ = strrep (output, " ", ""); + endif + + version = __version__; + +endfunction +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__go_draw_axes__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,2456 @@ +## Copyright (C) 2005-2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} __go_draw_axes__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono}) +## Undocumented internal function. +## @end deftypefn + +## Author: jwe + +function __go_draw_axes__ (h, plot_stream, enhanced, mono, + bg_is_set, fg_is_set, hlgnd) + + if (nargin >= 4 && nargin <= 7) + + showhiddenhandles = get (0, "showhiddenhandles"); + unwind_protect + set (0, "showhiddenhandles", "on"); + axis_obj = __get__ (h); + unwind_protect_cleanup + set (0, "showhiddenhandles", showhiddenhandles); + end_unwind_protect + + parent_figure_obj = get (axis_obj.parent); + gnuplot_term = __gnuplot_get_var__ (axis_obj.parent, "GPVAL_TERM"); + + ## Set to false for plotyy axes. + if (strcmp (axis_obj.tag, "plotyy")) + ymirror = false; + else + ymirror = true; + endif + + nd = __calc_dimensions__ (h); + + if (strcmp (axis_obj.dataaspectratiomode, "manual") + && strcmp (axis_obj.xlimmode, "manual") + && strcmp (axis_obj.ylimmode, "manual")) + ## All can't be "manual" + axis_obj.plotboxaspectratiomode = "auto"; + endif + + if (strcmp (axis_obj.dataaspectratiomode, "manual") + && strcmp (axis_obj.xlimmode, "manual") + && strcmp (axis_obj.ylimmode, "manual") + && (nd == 2 || all (mod (axis_obj.view, 90) == 0))) + ## FIXME - adjust plotboxaspectratio to respect other + fpos = get (axis_obj.parent, "position"); + apos = axis_obj.position; + endif + + pos = __actual_axis_position__ (h); + + if (strcmpi (axis_obj.dataaspectratiomode, "manual")) + dr = axis_obj.dataaspectratio; + if (nd == 2 || all (mod (axis_obj.view, 90) == 0)) + dr = dr(1) / dr(2); + else + ## FIXME - need to properly implement 3D + dr = mean (dr(1:2)) / dr(3); + endif + else + dr = 1; + endif + + if (strcmp (axis_obj.activepositionproperty, "position")) + if (__gnuplot_has_feature__ ("screen_coordinates_for_{lrtb}margin")) + if (nd == 2 || all (mod (axis_obj.view, 90) == 0)) + x = [1, 1]; + else + ## 3D plots need to be sized down to fit in the window. + x = 1.0 ./ sqrt([2, 2.5]); + endif + fprintf (plot_stream, "set tmargin screen %.15g;\n", + pos(2)+pos(4)/2+x(2)*pos(4)/2); + fprintf (plot_stream, "set bmargin screen %.15g;\n", + pos(2)+pos(4)/2-x(2)*pos(4)/2); + fprintf (plot_stream, "set lmargin screen %.15g;\n", + pos(1)+pos(3)/2-x(1)*pos(3)/2); + fprintf (plot_stream, "set rmargin screen %.15g;\n", + pos(1)+pos(3)/2+x(1)*pos(3)/2); + sz_str = ""; + else + fprintf (plot_stream, "set tmargin 0;\n"); + fprintf (plot_stream, "set bmargin 0;\n"); + fprintf (plot_stream, "set lmargin 0;\n"); + fprintf (plot_stream, "set rmargin 0;\n"); + + if (nd == 3 && all (axis_obj.view == [0, 90])) + ## FIXME -- Kludge to allow colorbar to be added to a pcolor() plot + pos(3:4) = pos(3:4) * 1.4; + pos(1:2) = pos(1:2) - pos(3:4) * 0.125; + endif + + fprintf (plot_stream, "set origin %.15g, %.15g;\n", pos(1), pos(2)); + + if (strcmpi (axis_obj.dataaspectratiomode, "manual")) + sz_str = sprintf ("set size ratio %.15g", -dr); + else + sz_str = "set size noratio"; + endif + sz_str = sprintf ("%s %.15g, %.15g;\n", sz_str, pos(3), pos(4)); + endif + else ## activepositionproperty == outerposition + fprintf (plot_stream, "unset tmargin;\n"); + fprintf (plot_stream, "unset bmargin;\n"); + fprintf (plot_stream, "unset lmargin;\n"); + fprintf (plot_stream, "unset rmargin;\n"); + fprintf (plot_stream, "set origin %g, %g;\n", pos(1:2)); + sz_str = ""; + if (strcmpi (axis_obj.dataaspectratiomode, "manual")) + sz_str = sprintf ("ratio %g", -dr); + else + sz_str = "noratio"; + endif + sz_str = sprintf ("set size %s %g, %g;\n", sz_str, pos(3:4)); + endif + if (! isempty (sz_str)) + fputs (plot_stream, sz_str); + endif + + ## Reset all labels, axis-labels, tick-labels, and title + ## FIXME - We should have an function to initialize the axis. + ## Presently, this is dispersed in this function. + fputs (plot_stream, "unset label;\n"); + fputs (plot_stream, "unset xtics;\n"); + fputs (plot_stream, "unset ytics;\n"); + fputs (plot_stream, "unset ztics;\n"); + fputs (plot_stream, "unset x2tics;\n"); + fputs (plot_stream, "unset x2tics;\n"); + + if (! isempty (axis_obj.title)) + t = get (axis_obj.title); + if (isempty (t.string)) + fputs (plot_stream, "unset title;\n"); + else + [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); + fontspec = create_fontspec (f, s, gnuplot_term); + fprintf (plot_stream, "set title \"%s\" %s %s;\n", + undo_string_escapes (tt), fontspec, + __do_enhanced_option__ (enhanced, t)); + endif + endif + + if (! isempty (axis_obj.xlabel)) + t = get (axis_obj.xlabel); + angle = t.rotation; + colorspec = get_text_colorspec (axis_obj.xcolor, mono); + if (isempty (t.string)) + fprintf (plot_stream, "unset xlabel;\n"); + fprintf (plot_stream, "unset x2label;\n"); + else + [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); + fontspec = create_fontspec (f, s, gnuplot_term); + if (strcmpi (axis_obj.xaxislocation, "top")) + fprintf (plot_stream, "set x2label \"%s\" %s %s %s", + undo_string_escapes (tt), colorspec, fontspec, + __do_enhanced_option__ (enhanced, t)); + else + fprintf (plot_stream, "set xlabel \"%s\" %s %s %s", + undo_string_escapes (tt), colorspec, fontspec, + __do_enhanced_option__ (enhanced, t)); + endif + fprintf (plot_stream, " rotate by %f;\n", angle); + if (strcmpi (axis_obj.xaxislocation, "top")) + fprintf (plot_stream, "unset xlabel;\n"); + else + fprintf (plot_stream, "unset x2label;\n"); + endif + endif + endif + + if (! isempty (axis_obj.ylabel)) + t = get (axis_obj.ylabel); + angle = t.rotation; + colorspec = get_text_colorspec (axis_obj.ycolor, mono); + if (isempty (t.string)) + fprintf (plot_stream, "unset ylabel;\n"); + fprintf (plot_stream, "unset y2label;\n"); + else + [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); + fontspec = create_fontspec (f, s, gnuplot_term); + if (strcmpi (axis_obj.yaxislocation, "right")) + fprintf (plot_stream, "set y2label \"%s\" %s %s %s", + undo_string_escapes (tt), colorspec, fontspec, + __do_enhanced_option__ (enhanced, t)); + else + fprintf (plot_stream, "set ylabel \"%s\" %s %s %s", + undo_string_escapes (tt), colorspec, fontspec, + __do_enhanced_option__ (enhanced, t)); + endif + fprintf (plot_stream, " rotate by %f;\n", angle); + if (strcmpi (axis_obj.yaxislocation, "right")) + fprintf (plot_stream, "unset ylabel;\n"); + else + fprintf (plot_stream, "unset y2label;\n"); + endif + endif + endif + + if (! isempty (axis_obj.zlabel)) + t = get (axis_obj.zlabel); + angle = t.rotation; + colorspec = get_text_colorspec (axis_obj.zcolor, mono); + if (isempty (t.string)) + fputs (plot_stream, "unset zlabel;\n"); + else + [tt, f, s] = __maybe_munge_text__ (enhanced, t, "string"); + fontspec = create_fontspec (f, s, gnuplot_term); + fprintf (plot_stream, "set zlabel \"%s\" %s %s %s", + undo_string_escapes (tt), colorspec, fontspec, + __do_enhanced_option__ (enhanced, t)); + fprintf (plot_stream, " rotate by %f;\n", angle); + endif + endif + + if (strcmpi (axis_obj.xaxislocation, "top")) + xaxisloc = "x2"; + xaxisloc_using = "x2"; + else + xaxisloc = "x"; + xaxisloc_using = "x1"; + if (strcmpi (axis_obj.xaxislocation, "zero")) + fputs (plot_stream, "set xzeroaxis;\n"); + endif + endif + if (strcmpi (axis_obj.yaxislocation, "right")) + yaxisloc = "y2"; + yaxisloc_using = "y2"; + else + yaxisloc = "y"; + yaxisloc_using = "y1"; + if (strcmpi (axis_obj.yaxislocation, "zero")) + fputs (plot_stream, "set yzeroaxis;\n"); + endif + endif + + have_grid = false; + + if (strcmpi (axis_obj.xgrid, "on")) + have_grid = true; + fprintf (plot_stream, "set grid %stics;\n", xaxisloc); + else + fprintf (plot_stream, "set grid no%stics;\n", xaxisloc); + endif + + if (strcmpi (axis_obj.ygrid, "on")) + have_grid = true; + fprintf (plot_stream, "set grid %stics;\n", yaxisloc); + else + fprintf (plot_stream, "set grid no%stics;\n", yaxisloc); + endif + + if (strcmpi (axis_obj.zgrid, "on")) + have_grid = true; + fputs (plot_stream, "set grid ztics;\n"); + else + fputs (plot_stream, "set grid noztics;\n"); + endif + + if (strcmpi (axis_obj.xminorgrid, "on")) + have_grid = true; + if (strcmp (axis_obj.xscale, "log")) + m = 10; + else + m = 5; + endif + fprintf (plot_stream, "set m%stics %d;\n", xaxisloc, m); + fprintf (plot_stream, "set grid m%stics;\n", xaxisloc); + else + fprintf (plot_stream, "set grid nom%stics;\n", xaxisloc); + endif + + if (strcmpi (axis_obj.yminorgrid, "on")) + have_grid = true; + if (strcmp (axis_obj.yscale, "log")) + m = 10; + else + m = 5; + endif + fprintf (plot_stream, "set m%stics %d;\n", yaxisloc, m); + fprintf (plot_stream, "set grid m%stics;\n", yaxisloc); + else + fprintf (plot_stream, "set grid nom%stics;\n", yaxisloc); + endif + + if (strcmpi (axis_obj.zminorgrid, "on")) + have_grid = true; + if (strcmp (axis_obj.zscale, "log")) + m = 10; + else + m = 5; + endif + fprintf (plot_stream, "set mztics %d;\n", m); + fputs (plot_stream, "set grid mztics;\n"); + else + fputs (plot_stream, "set grid nomztics;\n"); + endif + + ## The grid front/back/layerdefault option also controls the + ## appearance of tics, so it is used even if the grid is absent. + if (strcmpi (axis_obj.layer, "top")) + fputs (plot_stream, "set grid front;\n"); + fputs (plot_stream, "set border front;\n"); + else + fputs (plot_stream, "set grid layerdefault;\n"); + ## FIXME -- the gnuplot help says that "layerdefault" should work + ## for set border too, but it fails for me with gnuplot 4.2.5. So + ## use "back" instead. + fputs (plot_stream, "set border back;\n"); + endif + + fprintf (plot_stream, "set grid linewidth %f, linewidth %f;\n", + axis_obj.linewidth, axis_obj.linewidth); + + if (! have_grid) + fputs (plot_stream, "unset grid;\n"); + endif + + do_tics (axis_obj, plot_stream, ymirror, mono, gnuplot_term); + + fputs (plot_stream, "unset logscale;\n"); + xlogscale = strcmpi (axis_obj.xscale, "log"); + ylogscale = strcmpi (axis_obj.yscale, "log"); + zlogscale = strcmpi (axis_obj.zscale, "log"); + if (xlogscale) + fprintf (plot_stream, "set logscale %s;\n", xaxisloc); + endif + if (ylogscale) + fprintf (plot_stream, "set logscale %s;\n", yaxisloc); + endif + if (zlogscale) + fputs (plot_stream, "set logscale z;\n"); + endif + + xautoscale = strcmpi (axis_obj.xlimmode, "auto"); + yautoscale = strcmpi (axis_obj.ylimmode, "auto"); + zautoscale = strcmpi (axis_obj.zlimmode, "auto"); + cautoscale = strcmpi (axis_obj.climmode, "auto"); + cdatadirect = false; + truecolor = false; + + fputs (plot_stream, "set clip two;\n"); + + kids = axis_obj.children; + ## Remove the axis labels and title from the children, and + ## preserved the original order. + [jnk, k] = setdiff (kids, [axis_obj.xlabel; axis_obj.ylabel; ... + axis_obj.zlabel; axis_obj.title]); + kids = kids (sort (k)); + + if (nd == 3) + fputs (plot_stream, "set parametric;\n"); + fputs (plot_stream, "set style data lines;\n"); + fputs (plot_stream, "set surface;\n"); + fputs (plot_stream, "unset contour;\n"); + endif + + data_idx = 0; + data = cell (); + is_image_data = []; + hidden_removal = NaN; + view_map = false; + + xlim = axis_obj.xlim; + ylim = axis_obj.ylim; + zlim = axis_obj.zlim; + clim = axis_obj.clim; + + if (! cautoscale && clim(1) == clim(2)) + clim(2)++; + endif + addedcmap = []; + + ximg_data = {}; + ximg_data_idx = 0; + + while (! isempty (kids)) + + obj = get (kids(end)); + if (isfield (obj, "units")) + units = obj.units; + unwind_protect + set (kids(end), "units", "data"); + obj = get (kids(end)); + unwind_protect_cleanup + set (kids(end), "units", units); + end_unwind_protect + endif + kids = kids(1:(end-1)); + + if (strcmpi (obj.visible, "off")) + continue; + endif + + if (xlogscale && isfield (obj, "xdata")) + obj.xdata(obj.xdata<=0) = NaN; + endif + if (ylogscale && isfield (obj, "ydata")) + obj.ydata(obj.ydata<=0) = NaN; + endif + if (zlogscale && isfield (obj, "zdata")) + obj.zdata(obj.zdata<=0) = NaN; + endif + + ## Check for facecolor interpolation for surfaces. + doing_interp_color = ... + isfield (obj, "facecolor") && strncmp (obj.facecolor, "interp", 6); + + switch (obj.type) + case "image" + img_data = obj.cdata; + img_xdata = obj.xdata; + img_ydata = obj.ydata; + + if (ndims (img_data) == 3) + truecolor = true; + elseif (strcmpi (obj.cdatamapping, "direct")) + cdatadirect = true; + endif + data_idx++; + is_image_data(data_idx) = true; + parametric(data_idx) = false; + have_cdata(data_idx) = false; + have_3d_patch(data_idx) = false; + + if (img_xdata(2) < img_xdata(1)) + img_xdata = img_xdata(2:-1:1); + img_data = img_data(:,end:-1:1,:); + elseif (img_xdata(1) == img_xdata(2)) + img_xdata = img_xdata(1) + [0, size(img_data,2)-1]; + endif + if (img_ydata(2) < img_ydata(1)) + img_ydata = img_ydata(2:-1:1); + img_data = img_data(end:-1:1,:,:); + elseif (img_ydata(1) == img_ydata(2)) + img_ydata = img_ydata(1) + [0, size(img_data,1)-1]; + endif + + [y_dim, x_dim] = size (img_data(:,:,1)); + if (x_dim > 1) + dx = abs (img_xdata(2)-img_xdata(1))/(x_dim-1); + else + x_dim = 2; + img_data = [img_data, img_data]; + dx = abs (img_xdata(2)-img_xdata(1)); + endif + if (y_dim > 1) + dy = abs (img_ydata(2)-img_ydata(1))/(y_dim-1); + else + y_dim = 2; + img_data = [img_data; img_data]; + dy = abs (img_ydata(2)-img_ydata(1)); + endif + + x_origin = min (img_xdata); + y_origin = min (img_ydata); + + if (ndims (img_data) == 3) + data{data_idx} = permute (img_data, [3, 1, 2])(:); + format = "1:2:3"; + imagetype = "rgbimage"; + else + data{data_idx} = img_data(:); + format = "1"; + imagetype = "image"; + endif + + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = sprintf ("binary array=%dx%d scan=yx origin=(%.15g,%.15g) dx=%.15g dy=%.15g using %s", + x_dim, y_dim, x_origin, y_origin, dx, dy, format); + withclause{data_idx} = sprintf ("with %s;", imagetype); + + case "line" + if (strncmp (obj.linestyle, "none", 4) + && (! isfield (obj, "marker") + || (isfield (obj, "marker") + && strncmp (obj.marker, "none", 4)))) + continue; + endif + data_idx++; + is_image_data(data_idx) = false; + parametric(data_idx) = true; + have_cdata(data_idx) = false; + have_3d_patch(data_idx) = false; + if (isempty (obj.displayname)) + titlespec{data_idx} = "title \"\""; + else + tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname")); + titlespec{data_idx} = cstrcat ("title \"", tmp, "\""); + endif + usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata)); + errbars = ""; + if (nd == 3) + xdat = obj.xdata(:); + ydat = obj.ydata(:); + if (! isempty (obj.zdata)) + zdat = obj.zdata(:); + else + zdat = zeros (size (xdat)); + endif + data{data_idx} = [xdat, ydat, zdat]'; + usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", numel (xdat)); + ## fputs (plot_stream, "set parametric;\n"); + else + xdat = obj.xdata(:); + ydat = obj.ydata(:); + data{data_idx} = [xdat, ydat]'; + usingclause{data_idx} = sprintf ("record=%d using ($1):($2) axes %s%s", + rows(xdat), xaxisloc_using, yaxisloc_using); + endif + + style = do_linestyle_command (obj, obj.color, data_idx, mono, + plot_stream, errbars); + + withclause{data_idx} = sprintf ("with %s linestyle %d", + style{1}, data_idx); + + if (length (style) > 1) + data_idx++; + is_image_data(data_idx) = is_image_data(data_idx - 1); + parametric(data_idx) = parametric(data_idx - 1); + have_cdata(data_idx) = have_cdata(data_idx - 1); + have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = usingclause{data_idx - 1}; + data{data_idx} = data{data_idx - 1}; + withclause{data_idx} = sprintf ("with %s linestyle %d", + style{2}, data_idx); + endif + if (length (style) > 2) + data_idx++; + is_image_data(data_idx) = is_image_data(data_idx - 1); + parametric(data_idx) = parametric(data_idx - 1); + have_cdata(data_idx) = have_cdata(data_idx - 1); + have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = usingclause{data_idx - 1}; + data{data_idx} = data{data_idx - 1}; + withclause{data_idx} = sprintf ("with %s linestyle %d", + style{3}, data_idx); + endif + + case "patch" + cmap = parent_figure_obj.colormap; + [nr, nc] = size (obj.xdata); + + if (! isempty (obj.cdata)) + cdat = obj.cdata; + if (strcmpi (obj.cdatamapping, "direct")) + cdatadirect = true; + endif + else + cdat = []; + endif + + data_3d_idx = NaN; + for i = 1:nc + xcol = obj.xdata(:,i); + ycol = obj.ydata(:,i); + if (nd == 3) + if (! isempty (obj.zdata)) + zcol = obj.zdata(:,i); + else + zcol = zeros (size (xcol)); + endif + endif + + if (! isnan (xcol) && ! isnan (ycol)) + ## Is the patch closed or not + if (strncmp (obj.facecolor, "none", 4)) + hidden_removal = false; + else + + if (isnan (hidden_removal)) + hidden_removal = true; + endif + if (nd == 3) + if (numel (xcol) > 3) + error ("__go_draw_axes__: gnuplot (as of v4.2) only supports 3D filled triangular patches"); + else + if (isnan (data_3d_idx)) + data_idx++; + data_3d_idx = data_idx; + is_image_data(data_idx) = false; + parametric(data_idx) = false; + have_cdata(data_idx) = true; + have_3d_patch(data_idx) = true; + withclause{data_3d_idx} = sprintf ("with pm3d"); + usingclause{data_3d_idx} = "using 1:2:3:4"; + data{data_3d_idx} = []; + endif + local_idx = data_3d_idx; + ccdat = NaN; + endif + else + data_idx++; + local_idx = data_idx; + is_image_data(data_idx) = false; + parametric(data_idx) = false; + have_cdata(data_idx) = false; + have_3d_patch(data_idx) = false; + endif + + if (i > 1 || isempty (obj.displayname)) + titlespec{local_idx} = "title \"\""; + else + tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname")); + titlespec{local_idx} = cstrcat ("title \"", tmp, "\""); + endif + if (isfield (obj, "facecolor")) + if ((strncmp (obj.facecolor, "flat", 4) + || strncmp (obj.facecolor, "interp", 6)) + && isfield (obj, "cdata")) + if (ndims (obj.cdata) == 2 + && (size (obj.cdata, 2) == nc + && (size (obj.cdata, 1) == 1 + || size (obj.cdata, 1) == 3))) + ccol = cdat (:, i); + elseif (ndims (obj.cdata) == 2 + && (size (obj.cdata, 1) == nc + && (size (obj.cdata, 2) == 1 + || size (obj.cdata, 2) == 3))) + ccol = cdat (i, :); + elseif (ndims (obj.cdata) == 3) + ccol = permute (cdat (:, i, :), [1, 3, 2]); + else + ccol = cdat; + endif + if (strncmp (obj.facecolor, "flat", 4)) + if (numel(ccol) == 3) + color = ccol; + elseif (nd == 3 && numel (xcol) == 3) + ccdat = ccol * ones (3,1); + else + r = 1 + round ((size (cmap, 1) - 1) + * (ccol - clim(1))/(clim(2) - clim(1))); + r = max (1, min (r, size (cmap, 1))); + color = cmap(r, :); + endif + elseif (strncmp (obj.facecolor, "interp", 6)) + if (nd == 3 && numel (xcol) == 3) + ccdat = ccol; + if (! isvector (ccdat)) + tmp = rows(cmap) + rows(addedcmap) + ... + [1 : rows(ccdat)]; + addedcmap = [addedcmap; ccdat]; + ccdat = tmp(:); + else + ccdat = ccdat(:); + endif + else + warning ("\"interp\" not supported, using 1st entry of cdata"); + r = 1 + round ((size (cmap, 1) - 1) * ccol(1)); + r = max (1, min (r, size (cmap, 1))); + color = cmap(r,:); + endif + endif + elseif (isnumeric (obj.facecolor)) + color = obj.facecolor; + else + color = [0, 1, 0]; + endif + else + color = [0, 1, 0]; + endif + + if (nd == 3 && numel (xcol) == 3) + if (isnan (ccdat)) + ccdat = (rows (cmap) + rows(addedcmap) + 1) * ones(3, 1); + addedcmap = [addedcmap; reshape(color, 1, 3)]; + endif + data{data_3d_idx} = [data{data_3d_idx}, ... + [[xcol; xcol(end)], [ycol; ycol(end)], ... + [zcol; zcol(end)], [ccdat; ccdat(end)]]']; + else + if (mono) + colorspec = ""; + elseif (__gnuplot_has_feature__ ("transparent_patches") + && isscalar (obj.facealpha)) + colorspec = sprintf ("lc rgb \"#%02x%02x%02x\" fillstyle transparent solid %f", + round (255*color), obj.facealpha); + else + colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", + round (255*color)); + endif + + withclause{data_idx} = sprintf ("with filledcurve %s", + colorspec); + data{data_idx} = [xcol, ycol]'; + usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", + numel (xcol)); + endif + endif + endif + + ## patch outline + if (!(strncmp (obj.edgecolor, "none", 4) + && (strncmp (obj.marker, "none", 4) + || (strncmp (obj.markeredgecolor, "none", 4) + && strncmp (obj.markerfacecolor, "none", 4))))) + + data_idx++; + is_image_data(data_idx) = false; + parametric(data_idx) = false; + have_cdata(data_idx) = false; + have_3d_patch(data_idx) = false; + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = sprintf ("record=%d", numel (obj.xdata)); + + if (isfield (obj, "markersize")) + mdat = obj.markersize / 3; + endif + + if (isfield (obj, "edgecolor")) + ## FIXME + ## This is the wrong thing to do as edgecolor, markeredgecolor + ## and markerfacecolor can have different values and we should + ## treat them seperately. However, the below allow the scatter + ## functions to work as expected, where only one of these values + ## is set + if (strncmp (obj.edgecolor, "none", 4)) + if (strncmp (obj.markeredgecolor, "none", 4)) + ec = obj.markerfacecolor; + else + ec = obj.markeredgecolor; + endif + else + ec = obj.edgecolor; + endif + + if ((strncmp (ec, "flat", 4) + || strncmp (ec, "interp", 6)) + && isfield (obj, "cdata")) + if (ndims (obj.cdata) == 2 + && (size (obj.cdata, 2) == nc + && (size (obj.cdata, 1) == 1 + || size (obj.cdata, 1) == 3))) + ccol = cdat (:, i); + elseif (ndims (obj.cdata) == 2 + && (size (obj.cdata, 1) == nc + && (size (obj.cdata, 2) == 1 + || size (obj.cdata, 2) == 3))) + ccol = cdat (i, :); + elseif (ndims (obj.cdata) == 3) + ccol = permute (cdat (:, i, :), [1, 3, 2]); + else + ccol = cdat; + endif + if (strncmp (ec, "flat", 4)) + if (numel(ccol) == 3) + color = ccol; + else + if (isscalar (ccol)) + ccol = repmat(ccol, numel (xcol), 1); + endif + color = "flat"; + have_cdata(data_idx) = true; + endif + elseif (strncmp (ec, "interp", 6)) + if (numel(ccol) == 3) + warning ("\"interp\" not supported, using 1st entry of cdata"); + color = ccol(1,:); + else + if (isscalar (ccol)) + ccol = repmat(ccol, numel (xcol), 1); + endif + color = "interp"; + have_cdata(data_idx) = true; + endif + endif + elseif (isnumeric (ec)) + color = ec; + else + color = [0, 0, 0]; + endif + else + color = [0, 0, 0]; + endif + + if (isfield (obj, "linestyle")) + switch (obj.linestyle) + case "-" + lt = "lt 1"; + case "--" + lt = "lt 2"; + case ":" + lt = "lt 3"; + case "-." + lt = "lt 6"; + case "none" + lt = ""; + otherwise + lt = ""; + endswitch + else + lt = ""; + endif + + if (isfield (obj, "linewidth")) + lw = sprintf("linewidth %f", obj.linewidth); + else + lw = ""; + endif + + [pt, pt2, obj] = gnuplot_pointtype (obj); + if (! isempty (pt)) + pt = sprintf ("pointtype %s", pt); + endif + if (! isempty (pt2)) + pt2 = sprintf ("pointtype %s", pt2); + endif + + if (mono) + colorspec = ""; + else + if (ischar (color)) + colorspec = "palette"; + else + colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", + round (255*color)); + endif + endif + + sidx = 1; + if (isempty (lt)) + style = ""; + else + style = "lines"; + endif + tmpwith = {}; + + facesame = true; + if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor") + && !strncmp (obj.markerfacecolor, "none", 4)) + if (strncmp (obj.markerfacecolor, "auto", 4) + || ! isnumeric (obj.markerfacecolor) + || (isnumeric (obj.markerfacecolor) + && isequal (color, obj.markerfacecolor))) + style = strcat (style, "points"); + if (isfield (obj, "markersize")) + if (length (mdat) == nc) + m = mdat(i); + else + m = mdat; + endif + ps = sprintf("pointsize %f", m / 3); + else + ps = ""; + endif + + tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", + style, lw, pt2, lt, ps, + colorspec); + else + facesame = false; + if (! isempty (style)) + tmpwith{sidx} = sprintf ("with %s %s %s %s", + style, lw, lt, + colorspec); + sidx ++; + endif + if (isnumeric (obj.markerfacecolor) && ! mono) + colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", + round (255*obj.markerfacecolor)); + endif + style = "points"; + if (isfield (obj, "markersize")) + if (length (mdat) == nc) + m = mdat(i); + else + m = mdat; + endif + ps = sprintf("pointsize %f", m / 3); + else + ps = ""; + endif + tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", + style, lw, pt2, lt, ps, + colorspec); + endif + endif + + if (isfield (obj, "markeredgecolor") + && !strncmp (obj.markeredgecolor, "none", 4)) + if (facesame && !isempty (pt) + && (strncmp (obj.markeredgecolor, "auto", 4) + || ! isnumeric (obj.markeredgecolor) + || (isnumeric (obj.markeredgecolor) + && isequal (color, obj.markeredgecolor)))) + if (sidx == 1 && ((length (style) == 5 + && strncmp (style, "lines", 5)) + || isempty (style))) + style = strcat (style, "points"); + if (isfield (obj, "markersize")) + if (length (mdat) == nc) + m = mdat(i); + else + m = mdat; + endif + ps = sprintf("pointsize %f", m / 3); + else + ps = ""; + endif + tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", + style, lw, pt, lt, ps, + colorspec); + endif + else + if (!isempty (style)) + if (length(tmpwith) < sidx || isempty (tmpwith{sidx})) + tmpwith{sidx} = sprintf ("with %s %s %s %s", + style, lw, lt, + colorspec); + endif + sidx ++; + endif + + if (!isempty (pt)) + if (! mono) + if (strncmp (obj.markeredgecolor, "auto", 4)) + colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", + round (255*color)); + elseif (isnumeric (obj.markeredgecolor) && ! mono) + colorspec = sprintf ("lc rgb \"#%02x%02x%02x\"", + round (255*obj.markeredgecolor)); + endif + endif + style = "points"; + if (isfield (obj, "markersize")) + if (length (mdat) == nc) + m = mdat(i); + else + m = mdat; + endif + ps = sprintf("pointsize %f", m / 3); + else + ps = ""; + endif + tmpwith{sidx} = sprintf ("with %s %s %s %s %s %s", + style, lw, pt, lt, ps, + colorspec); + endif + endif + endif + + if (isempty (tmpwith)) + withclause{data_idx} = sprintf ("with %s %s %s %s %s", + style, lw, pt, lt, + colorspec); + else + withclause{data_idx} = tmpwith{1}; + endif + if (nd == 3) + if (ischar (color)) + if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol)) + data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... + [zcol; zcol(1)], [ccol; ccol(1)]]'; + else + data{data_idx} = [xcol, ycol, zcol, ccol]'; + endif + usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3):($4)", columns (data{data_idx})); + else + if (! isnan (xcol) && ! isnan (ycol) && ! isnan (zcol)) + data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... + [zcol; zcol(1)]]'; + else + data{data_idx} = [xcol, ycol, zcol]'; + endif + usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx})); + endif + else + if (ischar (color)) + if (! isnan (xcol) && ! isnan (ycol)) + data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)], ... + [ccol; ccol(1)]]'; + else + data{data_idx} = [xcol, ycol, ccol]'; + endif + usingclause{data_idx} = sprintf ("record=%d using ($1):($2):($3)", columns (data{data_idx})); + else + if (! isnan (xcol) && ! isnan (ycol)) + data{data_idx} = [[xcol; xcol(1)], [ycol; ycol(1)]]'; + else + data{data_idx} = [xcol, ycol]'; + endif + usingclause{data_idx} = sprintf ("record=%d using ($1):($2)", columns (data{data_idx})); + endif + endif + + if (length (tmpwith) > 1) + data_idx++; + is_image_data(data_idx) = is_image_data(data_idx - 1); + parametric(data_idx) = parametric(data_idx - 1); + have_cdata(data_idx) = have_cdata(data_idx - 1); + have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = usingclause{data_idx - 1}; + data{data_idx} = data{data_idx - 1}; + withclause{data_idx} = tmpwith{2}; + endif + if (length (tmpwith) > 2) + data_idx++; + is_image_data(data_idx) = is_image_data(data_idx - 1); + parametric(data_idx) = parametric(data_idx - 1); + have_cdata(data_idx) = have_cdata(data_idx - 1); + have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = usingclause{data_idx - 1}; + data{data_idx} = data{data_idx - 1}; + withclause{data_idx} = tmpwith{3}; + endif + endif + endfor + + case "surface" + view_map = true; + if (! (strncmp (obj.edgecolor, "none", 4) + && strncmp (obj.facecolor, "none", 4))) + data_idx++; + is_image_data(data_idx) = false; + parametric(data_idx) = false; + have_cdata(data_idx) = true; + have_3d_patch(data_idx) = false; + style = do_linestyle_command (obj, obj.edgecolor, + data_idx, mono, + plot_stream); + + if (isempty (obj.displayname)) + titlespec{data_idx} = "title \"\""; + else + tmp = undo_string_escapes (__maybe_munge_text__ (enhanced, obj, "displayname")); + titlespec{data_idx} = cstrcat ("title \"", tmp, "\""); + endif + withclause{data_idx} = sprintf ("with pm3d linestyle %d", + data_idx); + withpm3d = true; + pm3didx = data_idx; + + xdat = obj.xdata; + ydat = obj.ydata; + zdat = obj.zdata; + cdat = obj.cdata; + + err = false; + if (! size_equal(zdat, cdat)) + err = true; + endif + if (isvector (xdat) && isvector (ydat) && ismatrix (zdat)) + if (rows (zdat) == length (ydat) + && columns (zdat) == length (xdat)) + [xdat, ydat] = meshgrid (xdat, ydat); + else + err = true; + endif + elseif (ismatrix (xdat) && ismatrix (ydat) && ismatrix (zdat)) + if (! size_equal (xdat, ydat, zdat)) + err = true; + endif + else + err = true; + endif + if (err) + error ("__go_draw_axes__: invalid grid data"); + endif + xlen = columns (zdat); + ylen = rows (zdat); + if (xlen == columns (xdat) && xlen == columns (ydat) + && ylen == rows (xdat) && ylen == rows (ydat)) + len = 4 * xlen; + zz = zeros (ylen, len); + k = 1; + for kk = 1:4:len + zz(:,kk) = xdat(:,k); + zz(:,kk+1) = ydat(:,k); + zz(:,kk+2) = zdat(:,k); + zz(:,kk+3) = cdat(:,k); + k++; + endfor + data{data_idx} = zz.'; + endif + + if (doing_interp_color) + interp_str = "interpolate 0, 0"; + else + ## No interpolation of facecolors. + interp_str = ""; + endif + usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3):($4)", ylen, xlen); + + flat_interp_face = (strncmp (obj.facecolor, "flat", 4) + || strncmp (obj.facecolor, "interp", 6)); + flat_interp_edge = (strncmp (obj.edgecolor, "flat", 4) + || strncmp (obj.edgecolor, "interp", 6)); + + facecolor_none_or_white = (strncmp (obj.facecolor, "none", 4) + || (isnumeric (obj.facecolor) + && all (obj.facecolor == 1))); + hidden_removal = false; + fputs (plot_stream, "set style increment default;\n"); + if (flat_interp_edge && facecolor_none_or_white) + withpm3d = false; + withclause{data_idx} = sprintf ("with %s palette", style {1}); + fputs (plot_stream, "unset pm3d\n"); + if (all (obj.facecolor == 1)) + hidden_removal = true; + endif + elseif (facecolor_none_or_white) + if (all (obj.facecolor == 1)) + hidden_removal = true; + endif + fputs(plot_stream,"unset pm3d;\n"); + fputs(plot_stream,"set style increment user;\n"); + withpm3d = false; + withclause{data_idx} = sprintf("with %s linestyle %d", + style{1}, data_idx); + fputs (plot_stream, "unset pm3d\n"); + endif + + if (doing_interp_color) + ## "depthorder" interferes with interpolation of colors. + dord = "scansautomatic"; + else + dord = "depthorder"; + endif + + if (flat_interp_face && strncmp (obj.edgecolor, "flat", 4)) + fprintf (plot_stream, "set pm3d explicit at s %s %s corners2color c3;\n", + interp_str, dord); + elseif (!facecolor_none_or_white) + if (strncmp (obj.edgecolor, "none", 4)) + if (__gnuplot_has_feature__ ("transparent_surface") + && isscalar (obj.facealpha)) + fprintf (plot_stream, + "set style fill transparent solid %f;\n", + obj.facealpha); + endif + fprintf (plot_stream, "set pm3d explicit at s %s corners2color c3;\n", + interp_str, dord); + else + fprintf (plot_stream, "set pm3d explicit at s hidden3d %d %s %s corners2color c3;\n", + data_idx, interp_str, dord); + + if (__gnuplot_has_feature__ ("transparent_surface") + && isscalar (obj.facealpha)) + fprintf (plot_stream, + "set style fill transparent solid %f;\n", + obj.facealpha); + endif + endif + endif + + zz = []; + if (length (style) > 1) + len = 3 * xlen; + zz = zeros (ylen, len); + k = 1; + for kk = 1:3:len + zz(:,kk) = xdat(:,k); + zz(:,kk+1) = ydat(:,k); + zz(:,kk+2) = zdat(:,k); + k++; + endfor + zz = zz.'; + + data_idx++; + is_image_data(data_idx) = is_image_data(data_idx - 1); + parametric(data_idx) = parametric(data_idx - 1); + have_cdata(data_idx) = false; + have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen); + data{data_idx} = zz; + withclause{data_idx} = sprintf ("with %s linestyle %d", + style{2}, data_idx); + + endif + if (length (style) > 2) + data_idx++; + is_image_data(data_idx) = is_image_data(data_idx - 1); + parametric(data_idx) = parametric(data_idx - 1); + have_cdata(data_idx) = false; + have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen); + data{data_idx} = zz; + withclause{data_idx} = sprintf ("with %s linestyle %d", + style{3}, data_idx); + endif + if (withpm3d && strncmp (style {1}, "linespoints", 11)) + if (isempty(zz)) + len = 3 * xlen; + zz = zeros (ylen, len); + k = 1; + for kk = 1:3:len + zz(:,kk) = xdat(:,k); + zz(:,kk+1) = ydat(:,k); + zz(:,kk+2) = zdat(:,k); + k++; + endfor + zz = zz.'; + endif + data_idx++; + is_image_data(data_idx) = is_image_data(data_idx - 1); + parametric(data_idx) = parametric(data_idx - 1); + have_cdata(data_idx) = false; + have_3d_patch(data_idx) = have_3d_patch(data_idx - 1); + titlespec{data_idx} = "title \"\""; + usingclause{data_idx} = sprintf ("record=%dx%d using ($1):($2):($3)", ylen, xlen); + data{data_idx} = zz; + withclause{data_idx} = sprintf ("with points linestyle %d", + pm3didx); + endif + endif + + case "text" + [label, f, s] = __maybe_munge_text__ (enhanced, obj, "string"); + fontspec = create_fontspec (f, s, gnuplot_term); + lpos = obj.position; + halign = obj.horizontalalignment; + valign = obj.verticalalignment; + angle = obj.rotation; + units = obj.units; + color = obj.color; + if (strcmpi (units, "normalized")) + units = "graph"; + elseif (strcmp (axis_obj.yaxislocation, "right") + && strcmp (units, "data")) + units = "second"; + else + units = ""; + endif + + if (isnumeric (color)) + colorspec = get_text_colorspec (color, mono); + endif + + switch valign + ## Text offset in characters. This relies on gnuplot for font metrics. + case "top" + dy = -0.5; + case "cap" + dy = -0.5; + case "middle" + dy = 0; + case "baseline" + dy = 0.5; + case "bottom" + dy = 0.5; + endswitch + ## Gnuplot's Character units are different for x/y and vary with fontsize. The aspect ratio + ## of 1:1.7 was determined by experiment to work for eps/ps/etc. For the MacOS aqua terminal + ## a value of 2.5 is needed. However, the difference is barely noticable. + dx_and_dy = [(-dy * sind (angle)), (dy * cosd(angle))] .* [1.7 1]; + + if (nd == 3) + ## This produces the desired vertical alignment in 3D. + fprintf (plot_stream, + "set label \"%s\" at %s %.15e,%.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n", + undo_string_escapes (label), units, lpos(1), + lpos(2), lpos(3), halign, angle, dx_and_dy, fontspec, + __do_enhanced_option__ (enhanced, obj), colorspec); + else + fprintf (plot_stream, + "set label \"%s\" at %s %.15e,%.15e %s rotate by %f offset character %f,%f %s %s front %s;\n", + undo_string_escapes (label), units, + lpos(1), lpos(2), halign, angle, dx_and_dy, fontspec, + __do_enhanced_option__ (enhanced, obj), colorspec); + endif + + case "hggroup" + ## Push group children into the kid list. + if (isempty (kids)) + kids = obj.children; + elseif (! isempty (obj.children)) + kids = [kids; obj.children]; + endif + + otherwise + error ("__go_draw_axes__: unknown object class, %s", + obj.type); + endswitch + + endwhile + + ## This is need to prevent warnings for rotations in 3D plots, while + ## allowing colorbars with contours. + if (nd == 2 || (data_idx > 1 && !view_map)) + fputs (plot_stream, "set pm3d implicit;\n"); + else + fputs (plot_stream, "set pm3d explicit;\n"); + endif + + if (isnan(hidden_removal) || hidden_removal) + fputs (plot_stream, "set hidden3d;\n"); + else + fputs (plot_stream, "unset hidden3d;\n"); + endif + + have_data = (! (isempty (data) || all (cellfun ("isempty", data)))); + + ## Note we don't use the [xy]2range of gnuplot as we don't use the + ## dual axis plotting features of gnuplot. + if (isempty (xlim)) + return; + endif + if (strcmpi (axis_obj.xdir, "reverse")) + xdir = "reverse"; + else + xdir = "noreverse"; + endif + fprintf (plot_stream, "set xrange [%.15e:%.15e] %s;\n", xlim, xdir); + if (strcmpi (axis_obj.xaxislocation, "top")) + fprintf (plot_stream, "set x2range [%.15e:%.15e] %s;\n", xlim, xdir); + endif + + if (isempty (ylim)) + return; + endif + if (strcmpi (axis_obj.ydir, "reverse")) + ydir = "reverse"; + else + ydir = "noreverse"; + endif + fprintf (plot_stream, "set yrange [%.15e:%.15e] %s;\n", ylim, ydir); + if (strcmpi (axis_obj.yaxislocation, "right")) + fprintf (plot_stream, "set y2range [%.15e:%.15e] %s;\n", ylim, ydir); + endif + + if (nd == 3) + if (isempty (zlim)) + return; + endif + if (strcmpi (axis_obj.zdir, "reverse")) + zdir = "reverse"; + else + zdir = "noreverse"; + endif + fprintf (plot_stream, "set zrange [%.15e:%.15e] %s;\n", zlim, zdir); + endif + + cmap = parent_figure_obj.colormap; + cmap_sz = rows(cmap); + if (! any (isinf (clim))) + if (truecolor || ! cdatadirect) + if (rows(addedcmap) > 0) + for i = 1:data_idx + if (have_3d_patch(i)) + data{i}(end,:) = clim(2) * (data{i}(end, :) - 0.5) / cmap_sz; + endif + endfor + fprintf (plot_stream, "set cbrange [%g:%g];\n", clim(1), clim(2) * + (cmap_sz + rows(addedcmap)) / cmap_sz); + else + fprintf (plot_stream, "set cbrange [%g:%g];\n", clim); + endif + else + fprintf (plot_stream, "set cbrange [1:%d];\n", cmap_sz + + rows (addedcmap)); + endif + endif + + if (strcmpi (axis_obj.box, "on")) + if (nd == 3) + fputs (plot_stream, "set border 4095;\n"); + else + fputs (plot_stream, "set border 431;\n"); + endif + else + if (nd == 3) + fputs (plot_stream, "set border 895;\n"); + elseif (! isempty (axis_obj.ytick)) + if (strcmpi (axis_obj.yaxislocation, "right")) + fprintf (plot_stream, "unset ytics; set y2tics %s nomirror\n", + axis_obj.tickdir); + if (strcmpi (axis_obj.xaxislocation, "top")) + fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n", + axis_obj.tickdir); + fputs (plot_stream, "set border 12;\n"); + else + fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n", + axis_obj.tickdir); + fputs (plot_stream, "set border 9;\n"); + endif + else + fprintf (plot_stream, "unset y2tics; set ytics %s nomirror\n", + axis_obj.tickdir); + if (strcmpi (axis_obj.xaxislocation, "top")) + fprintf (plot_stream, "unset xtics; set x2tics %s nomirror\n", + axis_obj.tickdir); + fputs (plot_stream, "set border 6;\n"); + else + fprintf (plot_stream, "unset x2tics; set xtics %s nomirror\n", + axis_obj.tickdir); + fputs (plot_stream, "set border 3;\n"); + endif + endif + endif + endif + + if (strcmpi (axis_obj.visible, "off")) + fputs (plot_stream, "unset border; unset tics\n"); + else + fprintf (plot_stream, "set border lw %f;\n", axis_obj.linewidth); + endif + + if (! isempty (hlgnd) && ! isempty (hlgnd.children) + && any (strcmpi (get (hlgnd.children, "visible"), "on"))) + if (strcmpi (hlgnd.box, "on")) + box = "box"; + else + box = "nobox"; + endif + if (strcmpi (hlgnd.orientation, "vertical")) + horzvert = "vertical"; + else + horzvert = "horizontal"; + endif + if (strcmpi (hlgnd.textposition, "right")) + reverse = "reverse"; + else + reverse = "noreverse"; + endif + inout = "inside"; + keypos = hlgnd.location; + if (ischar (keypos)) + keypos = lower (keypos); + keyout = findstr (keypos, "outside"); + if (! isempty (keyout)) + inout = "outside"; + keypos = keypos(1:keyout-1); + endif + endif + switch (keypos) + case "north" + pos = "center top"; + case "south" + pos = "center bottom"; + case "east" + pos = "right center"; + case "west" + pos = "left center"; + case "northeast" + pos = "right top"; + case "northwest" + pos = "left top"; + case "southeast" + pos = "right bottom"; + case "southwest" + pos = "left bottom"; + case "best" + pos = ""; + warning ("legend: 'Best' not yet implemented for location specifier.\n"); + ## Least conflict with data in plot. + ## Least unused space outside plot. + otherwise + pos = ""; + endswitch + if (__gnuplot_has_feature__ ("key_has_font_properties")) + [fontname, fontsize] = get_fontname_and_size (hlgnd); + fontspec = create_fontspec (fontname, fontsize, gnuplot_term); + else + fontspec = ""; + endif + fprintf (plot_stream, "set key %s %s;\nset key %s %s %s %s;\n", + inout, pos, box, reverse, horzvert, fontspec); + else + fputs (plot_stream, "unset key;\n"); + endif + fputs (plot_stream, "set style data lines;\n"); + + cmap = [cmap; addedcmap]; + cmap_sz = cmap_sz + rows(addedcmap); + if (length(cmap) > 0) + fprintf (plot_stream, + "set palette positive color model RGB maxcolors %i;\n", + cmap_sz); + fprintf (plot_stream, + "set palette file \"-\" binary record=%d using 1:2:3:4;\n", + cmap_sz); + fwrite (plot_stream, [1:cmap_sz; cmap.'], "float32"); + fwrite (plot_stream, "\n"); + endif + + fputs (plot_stream, "unset colorbox;\n"); + + if (have_data) + if (nd == 2) + plot_cmd = "plot"; + else + plot_cmd = "splot"; + rot_x = 90 - axis_obj.view(2); + rot_z = axis_obj.view(1); + while (rot_z < 0) + rot_z += 360; + endwhile + fputs (plot_stream, "set ticslevel 0;\n"); + if (view_map && rot_x == 0 && rot_z == 0) + fputs (plot_stream, "set view map;\n"); + else + fprintf (plot_stream, "set view %.15g, %.15g;\n", rot_x, rot_z); + endif + endif + if (have_3d_patch (1)) + fputs (plot_stream, "set pm3d depthorder\n"); + fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, + usingclause{1}, titlespec{1}, withclause{1}); + elseif (is_image_data (1)) + fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, + usingclause{1}, titlespec{1}, withclause{1}); + else + fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd, + usingclause{1}, titlespec{1}, withclause{1}); + endif + for i = 2:data_idx + if (have_3d_patch (i)) + fprintf (plot_stream, ", \"-\" %s %s %s \\\n", + usingclause{i}, titlespec{i}, withclause{i}); + elseif (is_image_data (i)) + if (! is_image_data (i-1)) + fputs (plot_stream, "; "); + if (bg_is_set) + fputs (plot_stream, "unset obj 1; \\\n"); + bg_is_set = false; + endif + if (fg_is_set) + fputs (plot_stream, "unset obj 2; \\\n"); + fg_is_set = false; + endif + endif + fprintf (plot_stream, "%s \"-\" %s %s %s \\\n", plot_cmd, + usingclause{i}, titlespec{i}, withclause{i}); + elseif (is_image_data (i-1)) + if (bg_is_set) + fputs (plot_stream, "unset obj 1; \\\n"); + bg_is_set = false; + endif + if (fg_is_set) + fputs (plot_stream, "unset obj 2; \\\n"); + fg_is_set = false; + endif + fprintf (plot_stream, "%s \"-\" binary format='%%float64' %s %s %s \\\n", plot_cmd, + usingclause{i}, titlespec{i}, withclause{i}); + else + fprintf (plot_stream, ", \"-\" binary format='%%float64' %s %s %s \\\n", + usingclause{i}, titlespec{i}, withclause{i}); + endif + endfor + fputs (plot_stream, ";\n"); + for i = 1:data_idx + if (have_3d_patch (i)) + ## Can't write 3d patch data as binary as can't plot more than + ## a single patch at a time and have to plot all patches together + ## so that the gnuplot depth ordering is done correctly + for j = 1 : 4 : columns(data{i}) + if (j != 1) + fputs (plot_stream, "\n\n"); + endif + fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j).'); + fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n\n", data{i}(:,j+1).'); + fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+2).'); + fprintf (plot_stream, "%.15g %.15g %.15g %.15g\n", data{i}(:,j+3).'); + endfor + fputs (plot_stream, "e\n"); + elseif (is_image_data(i)) + fwrite (plot_stream, data{i}, "float32"); + else + __gnuplot_write_data__ (plot_stream, data{i}, nd, parametric(i), + have_cdata(i)); + endif + endfor + else + fputs (plot_stream, "plot \"-\";\nInf Inf\ne\n"); + endif + + ## Needed to allow mouse rotation with pcolor. + if (view_map) + fputs (plot_stream, "unset view;\n"); + endif + + if (bg_is_set) + fputs (plot_stream, "unset obj 1;\n"); + bg_is_set = false; + endif + + fflush (plot_stream); + + else + print_usage (); + endif + +endfunction + +function fontspec = create_fontspec (f, s, gp_term) + if (strcmp (f, "*") || strcmp (gp_term, "tikz")) + fontspec = sprintf ("font \",%d\"", s); + else + fontspec = sprintf ("font \"%s,%d\"", f, s); + endif +endfunction + +function style = do_linestyle_command (obj, linecolor, idx, mono, + plot_stream, errbars = "") + style = {}; + + fprintf (plot_stream, "set style line %d default;\n", idx); + fprintf (plot_stream, "set style line %d", idx); + + found_style = false; + if (isnumeric (linecolor)) + color = linecolor; + if (! mono) + fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", + round (255*color)); + endif + else + color = [0, 0, 0]; + endif + + if (isfield (obj, "linestyle")) + switch (obj.linestyle) + case "-" + lt = "1"; + case "--" + lt = "2"; + case ":" + lt = "3"; + case "-." + lt = "6"; + case "none" + lt = ""; + otherwise + lt = ""; + endswitch + + if (! isempty (lt)) + fprintf (plot_stream, " linetype %s", lt); + endif + + else + lt = ""; + endif + if (! isempty (errbars)) + found_style = true; + endif + + if (isfield (obj, "linewidth")) + fprintf (plot_stream, " linewidth %f", obj.linewidth); + found_style = true; + endif + + [pt, pt2, obj] = gnuplot_pointtype (obj); + + if (! isempty (pt)) + found_style = true; + endif + + sidx = 1; + if (isempty (errbars)) + if (isempty (lt)) + style {sidx} = ""; + else + style {sidx} = "lines"; + endif + + facesame = true; + if (! isequal (pt, pt2) && isfield (obj, "markerfacecolor") + && !strncmp (obj.markerfacecolor, "none", 4)) + if (strncmp (obj.markerfacecolor, "auto", 4) + || ! isnumeric (obj.markerfacecolor) + || (isnumeric (obj.markerfacecolor) + && isequal (color, obj.markerfacecolor))) + if (! isempty (pt2)) + fprintf (plot_stream, " pointtype %s", pt2); + style {sidx} = strcat (style{sidx}, "points"); + endif + if (isfield (obj, "markersize")) + fprintf (plot_stream, " pointsize %f", obj.markersize / 3); + endif + else + facesame = false; + if (! found_style) + fputs (plot_stream, " default"); + endif + fputs (plot_stream, ";\n"); + if (! isempty (style {sidx})) + sidx ++; + idx ++; + else + fputs (plot_stream, ";\n"); + endif + fprintf (plot_stream, "set style line %d default;\n", idx); + fprintf (plot_stream, "set style line %d", idx); + if (isnumeric (obj.markerfacecolor) && ! mono) + fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", + round (255*obj.markerfacecolor)); + endif + if (! isempty (pt2)) + style {sidx} = "points"; + fprintf (plot_stream, " pointtype %s", pt2); + endif + if (isfield (obj, "markersize")) + fprintf (plot_stream, " pointsize %f", obj.markersize / 3); + endif + endif + endif + if (isfield (obj, "markeredgecolor") + && !strncmp (obj.markeredgecolor, "none", 4)) + if (facesame && !isempty (pt) + && (strncmp (obj.markeredgecolor, "auto", 4) + || ! isnumeric (obj.markeredgecolor) + || (isnumeric (obj.markeredgecolor) + && isequal (color, obj.markeredgecolor)))) + if (sidx == 1 && ((length (style {sidx}) == 5 + && strncmp (style {sidx}, "lines", 5)) || isempty (style {sidx}))) + if (! isempty (pt)) + style {sidx} = strcat (style{sidx}, "points"); + fprintf (plot_stream, " pointtype %s", pt); + endif + if (isfield (obj, "markersize")) + fprintf (plot_stream, " pointsize %f", obj.markersize / 3); + endif + endif + else + if (! found_style) + fputs (plot_stream, " default"); + endif + fputs (plot_stream, ";\n"); + if (!isempty (style {sidx})) + sidx ++; + idx ++; + else + fputs (plot_stream, ";\n"); + endif + fprintf (plot_stream, "set style line %d default;\n", idx); + fprintf (plot_stream, "set style line %d", idx); + if (! mono) + if (strncmp (obj.markeredgecolor, "auto", 4)) + fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", + round (255*color)); + elseif (isnumeric (obj.markeredgecolor) && ! mono) + fprintf (plot_stream, " linecolor rgb \"#%02x%02x%02x\"", + round (255*obj.markeredgecolor)); + endif + endif + if (! isempty (pt)) + style {sidx} = "points"; + fprintf (plot_stream, " pointtype %s", pt); + endif + if (isfield (obj, "markersize")) + fprintf (plot_stream, " pointsize %f", obj.markersize / 3); + endif + endif + endif + else + style{1} = errbars; + fputs (plot_stream, " pointtype 0"); + endif + + if (! found_style && isempty (style {1})) + fputs (plot_stream, " default"); + endif + + fputs (plot_stream, ";\n"); + +endfunction + +function [pt, pt2, obj] = gnuplot_pointtype (obj) + if (isfield (obj, "marker")) + switch (obj.marker) + case "+" + pt = pt2 = "1"; + case "o" + pt = "6"; + pt2 = "7"; + case "*" + pt = pt2 = "3"; + case "." + pt = "6"; + pt2 = "7"; + if (isfield (obj, "markerfacecolor") + || strncmp (obj.markerfacecolor, "none", 4)) + obj.markerfacecolor = "auto"; + endif + if (isfield (obj, "markersize")) + obj.markersize /= 3; + else + obj.markersize = 5; + endif + case "x" + pt = pt2 = "2"; + case {"square", "s"} + pt = "4"; + pt2 = "5"; + case {"diamond", "d"} + pt = "12"; + pt2 = "13"; + case "^" + pt = "8"; + pt2 = "9"; + case "v" + pt = "10"; + pt2 = "11"; + case ">" + ## FIXME -- should be triangle pointing right, use triangle pointing up + pt = "8"; + pt2 = "9"; + case "<" + ## FIXME -- should be triangle pointing left, use triangle pointing down + pt = "10"; + pt2 = "11"; + case {"pentagram", "p"} + ## FIXME -- should be pentagram, using pentagon + pt = "14"; + pt2 = "15"; + case {"hexagram", "h"} + ## FIXME -- should be 6 pt start, using "*" instead + pt = pt2 = "3"; + case "none" + pt = pt2 = ""; + otherwise + pt = pt2 = ""; + endswitch + else + pt = pt2 = ""; + endif +endfunction + +function __gnuplot_write_data__ (plot_stream, data, nd, parametric, cdata) + + ## DATA is already transposed. + + ## FIXME -- this may need to be converted to C++ for speed. + + ## Convert NA elements to normal NaN values because fprintf writes + ## "NA" and that confuses gnuplot. + idx = find (isna (data)); + if (any (idx)) + data(idx) = NaN; + endif + + if (nd == 2) + fwrite (plot_stream, data, "float64"); + elseif (nd == 3) + if (parametric) + fwrite (plot_stream, data, "float64"); + else + nr = rows (data); + if (cdata) + for j = 1:4:nr + fwrite (plot_stream, data(j:j+3,:), "float64"); + endfor + else + for j = 1:3:nr + fwrite (plot_stream, data(j:j+2,:), "float64"); + endfor + endif + endif + endif + +endfunction + +function do_tics (obj, plot_stream, ymirror, mono, gnuplot_term) + + obj.xticklabel = ticklabel_to_cell (obj.xticklabel); + obj.yticklabel = ticklabel_to_cell (obj.yticklabel); + obj.zticklabel = ticklabel_to_cell (obj.zticklabel); + + if (strcmp (obj.xminorgrid, "on")) + obj.xminortick = "on"; + endif + if (strcmp (obj.yminorgrid, "on")) + obj.yminortick = "on"; + endif + if (strcmp (obj.zminorgrid, "on")) + obj.zminortick = "on"; + endif + + [fontname, fontsize] = get_fontname_and_size (obj); + fontspec = create_fontspec (fontname, fontsize, gnuplot_term); + + ## A Gnuplot tic scale of 69 is equivalent to Octave's 0.5. + ticklength = sprintf ("scale %4.1f", (69/0.5)*obj.ticklength(1)); + + if (strcmpi (obj.xaxislocation, "top")) + do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, + obj.xticklabel, obj.xcolor, "x2", plot_stream, true, mono, + "border", obj.tickdir, ticklength, fontname, fontspec, + obj.interpreter, obj.xscale); + do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, + obj.xcolor, "x", plot_stream, true, mono, "border", + "", "", fontname, fontspec, obj.interpreter, obj.xscale); + elseif (strcmpi (obj.xaxislocation, "zero")) + do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, + obj.xticklabel, obj.xcolor, "x", plot_stream, true, mono, + "axis", obj.tickdir, ticklength, fontname, fontspec, + obj.interpreter, obj.xscale); + do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, + obj.xcolor, "x2", plot_stream, true, mono, "axis", + "", "", fontname, fontspec, obj.interpreter, obj.xscale); + else + do_tics_1 (obj.xtickmode, obj.xtick, obj.xminortick, obj.xticklabelmode, + obj.xticklabel, obj.xcolor, "x", plot_stream, true, mono, + "border", obj.tickdir, ticklength, fontname, fontspec, + obj.interpreter, obj.xscale); + do_tics_1 ("manual", [], "off", obj.xticklabelmode, obj.xticklabel, + obj.xcolor, "x2", plot_stream, true, mono, "border", + "", "", fontname, fontspec, obj.interpreter, obj.xscale); + endif + if (strcmpi (obj.yaxislocation, "right")) + do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, + obj.yticklabel, obj.ycolor, "y2", plot_stream, ymirror, mono, + "border", obj.tickdir, ticklength, fontname, fontspec, + obj.interpreter, obj.yscale); + do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, + obj.ycolor, "y", plot_stream, ymirror, mono, "border", + "", "", fontname, fontspec, obj.interpreter, obj.yscale); + elseif (strcmpi (obj.yaxislocation, "zero")) + do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, + obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, mono, + "axis", obj.tickdir, ticklength, fontname, fontspec, + obj.interpreter, obj.yscale); + do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, + obj.ycolor, "y2", plot_stream, ymirror, mono, "axis", + "", "", fontname, fontspec, obj.interpreter, obj.yscale); + else + do_tics_1 (obj.ytickmode, obj.ytick, obj.yminortick, obj.yticklabelmode, + obj.yticklabel, obj.ycolor, "y", plot_stream, ymirror, mono, + "border", obj.tickdir, ticklength, fontname, fontspec, + obj.interpreter, obj.yscale); + do_tics_1 ("manual", [], "off", obj.yticklabelmode, obj.yticklabel, + obj.ycolor, "y2", plot_stream, ymirror, mono, "border", + "", "", fontname, fontspec, obj.interpreter, obj.yscale); + endif + do_tics_1 (obj.ztickmode, obj.ztick, obj.zminortick, obj.zticklabelmode, + obj.zticklabel, obj.zcolor, "z", plot_stream, true, mono, + "border", obj.tickdir, ticklength, fontname, fontspec, + obj.interpreter, obj.zscale); +endfunction + +function do_tics_1 (ticmode, tics, mtics, labelmode, labels, color, ax, + plot_stream, mirror, mono, axispos, tickdir, ticklength, + fontname, fontspec, interpreter, scale) + persistent warned_latex = false; + if (strcmpi (interpreter, "tex")) + for n = 1 : numel(labels) + labels{n} = __tex2enhanced__ (labels{n}, fontname, false, false); + endfor + elseif (strcmpi (interpreter, "latex")) + if (! warned_latex) + warning ("latex markup not supported for tick marks"); + warned_latex = true; + endif + endif + if (strcmp (scale, "log")) + fmt = "10^{%T}"; + num_mtics = 10; + else + fmt = "%g"; + num_mtics = 5; + endif + colorspec = get_text_colorspec (color, mono); + if (strcmpi (ticmode, "manual") || strcmpi (labelmode, "manual")) + if (isempty (tics)) + fprintf (plot_stream, "unset %stics;\nunset m%stics;\n", ax, ax); + elseif (strcmpi (labelmode, "manual")) + if (ischar (labels)) + labels = cellstr (labels); + endif + if (isnumeric (labels)) + labels = num2str (real (labels(:))); + endif + if (ischar (labels)) + labels = permute (cellstr (labels), [2, 1]); + endif + if (iscellstr (labels)) + k = 1; + ntics = numel (tics); + nlabels = numel (labels); + fprintf (plot_stream, "set format %s \"%%s\";\n", ax); + if (mirror) + fprintf (plot_stream, "set %stics %s %s %s mirror (", ax, + tickdir, ticklength, axispos); + else + fprintf (plot_stream, "set %stics %s %s %s nomirror (", ax, + tickdir, ticklength, axispos); + endif + + labels = regexprep(labels, '%', "%%"); + for i = 1:ntics + fprintf (plot_stream, " \"%s\" %.15g", labels{k++}, tics(i)); + if (i < ntics) + fputs (plot_stream, ", "); + endif + if (k > nlabels) + k = 1; + endif + endfor + fprintf (plot_stream, ") %s %s;\n", colorspec, fontspec); + if (strcmp (mtics, "on")) + fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics); + else + fprintf (plot_stream, "unset m%stics;\n", ax); + endif + else + error ("__go_draw_axes__: unsupported type of ticklabel"); + endif + else + fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt); + if (mirror) + fprintf (plot_stream, "set %stics %s %s %s mirror (", ax, tickdir, + ticklength, axispos); + else + fprintf (plot_stream, "set %stics %s %s %s nomirror (", ax, tickdir, + ticklength, axispos); + endif + fprintf (plot_stream, " %.15g,", tics(1:end-1)); + fprintf (plot_stream, " %.15g) %s;\n", tics(end), fontspec); + if (strcmp (mtics, "on")) + fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics); + else + fprintf (plot_stream, "unset m%stics;\n", ax); + endif + endif + else + fprintf (plot_stream, "set format %s \"%s\";\n", ax, fmt); + if (mirror) + fprintf (plot_stream, "set %stics %s %s %s mirror %s %s;\n", ax, + axispos, tickdir, ticklength, colorspec, fontspec); + else + fprintf (plot_stream, "set %stics %s %s %s nomirror %s %s;\n", ax, + tickdir, ticklength, axispos, colorspec, fontspec); + endif + if (strcmp (mtics, "on")) + fprintf (plot_stream, "set m%stics %d;\n", ax, num_mtics); + else + fprintf (plot_stream, "unset m%stics;\n", ax); + endif + endif +endfunction + +function ticklabel = ticklabel_to_cell (ticklabel) + if (isnumeric (ticklabel)) + ## Use upto 5 significant digits + ticklabel = num2str (ticklabel(:), 5); + endif + if (ischar (ticklabel)) + if (size (ticklabel, 1) == 1 && any (ticklabel == "|")) + n = setdiff (findstr (ticklabel, "|"), findstr (ticklabel, '\|')); + ticklabel = strsplit (ticklabel, "|"); + else + ticklabel = cellstr (ticklabel); + endif + elseif (isempty (ticklabel)) + ticklabel = {""}; + else + ticklabel = ticklabel; + endif +endfunction + +function colorspec = get_text_colorspec (color, mono) + if (mono) + colorspec = ""; + else + colorspec = sprintf ("textcolor rgb \"#%02x%02x%02x\"", + round (255*color)); + endif +endfunction + +function [f, s, fnt, it, bld] = get_fontname_and_size (t) + if (isempty (t.fontname) || strcmp (t.fontname, "*")) + fnt = "{}"; + else + fnt = t.fontname; + endif + f = fnt; + it = false; + bld = false; + if (! isempty (t.fontweight) && strcmpi (t.fontweight, "bold")) + if (! isempty(t.fontangle) + && (strcmpi (t.fontangle, "italic") + || strcmpi (t.fontangle, "oblique"))) + f = cstrcat (f, "-bolditalic"); + it = true; + bld = true; + else + f = cstrcat (f, "-bold"); + bld = true; + endif + elseif (! isempty(t.fontangle) + && (strcmpi (t.fontangle, "italic") + || strcmpi (t.fontangle, "oblique"))) + f = cstrcat (f, "-italic"); + it = true; + endif + if (isempty (t.fontsize)) + s = 10; + else + s = t.fontsize; + endif +endfunction + +function [str, f, s] = __maybe_munge_text__ (enhanced, obj, fld) + + persistent warned_latex = false; + + if (strcmp (fld, "string")) + [f, s, fnt, it, bld] = get_fontname_and_size (obj); + else + f = "Helvetica"; + s = 10; + fnt = f; + it = false; + bld = false; + endif + + str = getfield (obj, fld); + if (enhanced) + if (strcmpi (obj.interpreter, "tex")) + str = __tex2enhanced__ (str, fnt, it, bld); + elseif (strcmpi (obj.interpreter, "latex")) + if (! warned_latex) + warning ("latex markup not supported for text objects"); + warned_latex = true; + endif + endif + endif +endfunction + +function str = __tex2enhanced__ (str, fnt, it, bld) + persistent sym = __setup_sym_table__ (); + persistent flds = fieldnames (sym); + + [s, e, m] = regexp(str,'\\([a-zA-Z]+|0)','start','end','matches'); + + for i = length (s) : -1 : 1 + ## special case for "\0" and replace with "{/Symbol \306}' + if (strncmp (m{i}, '\0', 2)) + str = cstrcat (str(1:s(i) - 1), '{/Symbol \306}', str(s(i) + 2:end)); + else + f = m{i}(2:end); + if (isfield (sym, f)) + g = getfield(sym, f); + ## FIXME The symbol font doesn't seem to support bold or italic + ##if (bld) + ## if (it) + ## g = regexprep (g, '/Symbol', '/Symbol-bolditalic'); + ## else + ## g = regexprep (g, '/Symbol', '/Symbol-bold'); + ## endif + ##elseif (it) + ## g = regexprep (g, '/Symbol', '/Symbol-italic'); + ##endif + str = cstrcat (str(1:s(i) - 1), g, str(e(i) + 1:end)); + elseif (strncmp (f, "rm", 2)) + bld = false; + it = false; + str = cstrcat (str(1:s(i) - 1), '/', fnt, ' ', str(s(i) + 3:end)); + elseif (strncmp (f, "it", 2) || strncmp (f, "sl", 2)) + it = true; + if (bld) + str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bolditalic ', + str(s(i) + 3:end)); + else + str = cstrcat (str(1:s(i) - 1), '/', fnt, '-italic ', + str(s(i) + 3:end)); + endif + elseif (strncmp (f, "bf", 2)) + bld = true; + if (it) + str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bolditalic ', + str(2(i) + 3:end)); + else + str = cstrcat (str(1:s(i) - 1), '/', fnt, '-bold ', + str(s(i) + 3:end)); + endif + elseif (strcmpi (f, "color")) + ## FIXME Ignore \color but remove trailing {} block as well + d = strfind(str(e(i) + 1:end),'}'); + if (isempty (d)) + warning ('syntax error in \color argument'); + else + str = cstrcat (str(1:s(i) - 1), str(e(i) + d + 1:end)); + endif + elseif(strcmpi (f, "fontname")) + b1 = strfind(str(e(i) + 1:end),'{'); + b2 = strfind(str(e(i) + 1:end),'}'); + if (isempty(b1) || isempty(b2)) + warning ('syntax error in \fontname argument'); + else + str = cstrcat (str(1:s(i) - 1), '/', + str(e(i)+b1(1) + 1:e(i)+b2(1)-1), '{}', + str(e(i) + b2(1) + 1:end)); + endif + elseif(strcmpi (f, "fontsize")) + b1 = strfind(str(e(i) + 1:end),'{'); + b2 = strfind(str(e(i) + 1:end),'}'); + if (isempty(b1) || isempty(b2)) + warning ('syntax error in \fontname argument'); + else + str = cstrcat (str(1:s(i) - 1), '/=', + str(e(i)+b1(1) + 1:e(i)+b2(1)-1), '{}', + str(e(i) + b2(1) + 1:end)); + endif + else + ## Last desperate attempt to treat the symbol. Look for things + ## like \pix, that should be translated to the symbol Pi and x + for j = 1 : length (flds) + if (strncmp (flds{j}, f, length (flds{j}))) + g = getfield(sym, flds{j}); + ## FIXME The symbol font doesn't seem to support bold or italic + ##if (bld) + ## if (it) + ## g = regexprep (g, '/Symbol', '/Symbol-bolditalic'); + ## else + ## g = regexprep (g, '/Symbol', '/Symbol-bold'); + ## endif + ##elseif (it) + ## g = regexprep (g, '/Symbol', '/Symbol-italic'); + ##endif + str = cstrcat (str(1:s(i) - 1), g, + str(s(i) + length (flds{j}) + 1:end)); + break; + endif + endfor + endif + endif + endfor + + ## Prepend @ to things things like _0^x or _{-100}^{100} for + ## alignment But need to put the shorter of the two arguments first. + ## Carful of nested {} and unprinted characters when defining + ## shortest.. Don't have to worry about things like ^\theta as they + ## are already converted to ^{/Symbol q}. + + ## FIXME -- This is a mess... Is it worth it just for a "@" character? + + [s, m] = regexp(str,'[_\^]','start','matches'); + i = 1; + p = 0; + while (i < length (s)) + if (i < length(s)) + if (str(s(i) + p + 1) == "{") + s1 = strfind(str(s(i) + p + 2:end),'{'); + si = 1; + l1 = strfind(str(s(i) + p + 1:end),'}'); + li = 1; + while (li <= length (l1) && si <= length (s1)) + if (l1(li) < s1(si)) + if (li == si) + break; + endif + li++; + else + si++; + endif + endwhile + l1 = l1 (min (length(l1), si)); + if (s(i) + l1 + 1 == s(i+1)) + if (str(s(i + 1) + p + 1) == "{") + s2 = strfind(str(s(i + 1) + p + 2:end),'{'); + si = 1; + l2 = strfind(str(s(i + 1) + p + 1:end),'}'); + li = 1; + while (li <= length (l2) && si <= length (s2)) + if (l2(li) < s2(si)) + if (li == si) + break; + endif + li++; + else + si++; + endif + endwhile + l2 = l2 (min (length(l2), si)); + if (length_string (str(s(i)+p+2:s(i)+p+l1-1)) <= + length_string(str(s(i+1)+p+2:s(i+1)+p+l2-1))) + ## Shortest already first! + str = cstrcat (str(1:s(i)+p-1), "@", str(s(i)+p:end)); + else + ## Have to swap sub/super-script to get shortest first. + str = cstrcat (str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+l2), + str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+l2+1:end)); + endif + else + ## Have to swap sub/super-script to get shortest first. + str = cstrcat (str(1:s(i)+p-1), "@", str(s(i+1)+p:s(i+1)+p+1), + str(s(i)+p:s(i)+p+l1), str(s(i+1)+p+2:end)); + endif + i += 2; + p ++; + else + i++; + endif + else + if (s(i+1) == s(i) + 2) + ## Shortest already first! + str = cstrcat (str(1:s(i)+p-1), "@", str(s(i)+p:end)); + p ++; + i += 2; + else + i ++; + endif + endif + else + i ++; + endif + endwhile + +endfunction + +function l = length_string (s) + l = length (s) - length (strfind(s,'{')) - length (strfind(s,'}')); + m = regexp (s, '/([\w-]+|[\w-]+=\d+)', 'matches'); + if (!isempty (m)) + l = l - sum (cellfun ("length", m)); + endif +endfunction + +function sym = __setup_sym_table__ () + ## Setup the translation table for TeX to gnuplot enhanced mode. + sym.forall = '{/Symbol \042}'; + sym.exists = '{/Symbol \044}'; + sym.ni = '{/Symbol \047}'; + sym.cong = '{/Symbol \100}'; + sym.Delta = '{/Symbol D}'; + sym.Phi = '{/Symbol F}'; + sym.Gamma = '{/Symbol G}'; + sym.vartheta = '{/Symbol J}'; + sym.Lambda = '{/Symbol L}'; + sym.Pi = '{/Symbol P}'; + sym.Theta = '{/Symbol Q}'; + sym.Sigma = '{/Symbol S}'; + sym.varsigma = '{/Symbol V}'; + sym.Omega = '{/Symbol W}'; + sym.Xi = '{/Symbol X}'; + sym.Psi = '{/Symbol Y}'; + sym.perp = '{/Symbol \136}'; + sym.alpha = '{/Symbol a}'; + sym.beta = '{/Symbol b}'; + sym.chi = '{/Symbol c}'; + sym.delta = '{/Symbol d}'; + sym.epsilon = '{/Symbol e}'; + sym.phi = '{/Symbol f}'; + sym.gamma = '{/Symbol g}'; + sym.eta = '{/Symbol h}'; + sym.iota = '{/Symbol i}'; + sym.varphi = '{/Symbol j}'; + sym.kappa = '{/Symbol k}'; + sym.lambda = '{/Symbol l}'; + sym.mu = '{/Symbol m}'; + sym.nu = '{/Symbol n}'; + sym.o = '{/Symbol o}'; + sym.pi = '{/Symbol p}'; + sym.theta = '{/Symbol q}'; + sym.rho = '{/Symbol r}'; + sym.sigma = '{/Symbol s}'; + sym.tau = '{/Symbol t}'; + sym.upsilon = '{/Symbol u}'; + sym.varpi = '{/Symbol v}'; + sym.omega = '{/Symbol w}'; + sym.xi = '{/Symbol x}'; + sym.psi = '{/Symbol y}'; + sym.zeta = '{/Symbol z}'; + sym.sim = '{/Symbol \176}'; + sym.Upsilon = '{/Symbol \241}'; + sym.prime = '{/Symbol \242}'; + sym.leq = '{/Symbol \243}'; + sym.infty = '{/Symbol \245}'; + sym.clubsuit = '{/Symbol \247}'; + sym.diamondsuit = '{/Symbol \250}'; + sym.heartsuit = '{/Symbol \251}'; + sym.spadesuit = '{/Symbol \252}'; + sym.leftrightarrow = '{/Symbol \253}'; + sym.leftarrow = '{/Symbol \254}'; + sym.uparrow = '{/Symbol \255}'; + sym.rightarrow = '{/Symbol \256}'; + sym.downarrow = '{/Symbol \257}'; + sym.circ = '{/Symbol \260}'; + sym.pm = '{/Symbol \261}'; + sym.geq = '{/Symbol \263}'; + sym.times = '{/Symbol \264}'; + sym.propto = '{/Symbol \265}'; + sym.partial = '{/Symbol \266}'; + sym.bullet = '{/Symbol \267}'; + sym.div = '{/Symbol \270}'; + sym.neq = '{/Symbol \271}'; + sym.equiv = '{/Symbol \272}'; + sym.approx = '{/Symbol \273}'; + sym.ldots = '{/Symbol \274}'; + sym.mid = '{/Symbol \275}'; + sym.aleph = '{/Symbol \300}'; + sym.Im = '{/Symbol \301}'; + sym.Re = '{/Symbol \302}'; + sym.wp = '{/Symbol \303}'; + sym.otimes = '{/Symbol \304}'; + sym.oplus = '{/Symbol \305}'; + sym.oslash = '{/Symbol \306}'; + sym.cap = '{/Symbol \307}'; + sym.cup = '{/Symbol \310}'; + sym.supset = '{/Symbol \311}'; + sym.supseteq = '{/Symbol \312}'; + sym.subset = '{/Symbol \314}'; + sym.subseteq = '{/Symbol \315}'; + sym.in = '{/Symbol \316}'; + sym.notin = '{/Symbol \317}'; + sym.angle = '{/Symbol \320}'; + sym.bigtriangledown = '{/Symbol \321}'; + sym.langle = '{/Symbol \341}'; + sym.rangle = '{/Symbol \361}'; + sym.nabla = '{/Symbol \321}'; + sym.prod = '{/Symbol \325}'; + sym.surd = '{/Symbol \326}'; + sym.cdot = '{/Symbol \327}'; + sym.neg = '{/Symbol \330}'; + sym.wedge = '{/Symbol \331}'; + sym.vee = '{/Symbol \332}'; + sym.Leftrightarrow = '{/Symbol \333}'; + sym.Leftarrow = '{/Symbol \334}'; + sym.Uparrow = '{/Symbol \335}'; + sym.Rightarrow = '{/Symbol \336}'; + sym.Downarrow = '{/Symbol \337}'; + sym.diamond = '{/Symbol \340}'; + sym.copyright = '{/Symbol \343}'; + sym.lfloor = '{/Symbol \353}'; + sym.lceil = '{/Symbol \351}'; + sym.rfloor = '{/Symbol \373}'; + sym.rceil = '{/Symbol \371}'; + sym.int = '{/Symbol \362}'; +endfunction + +function retval = __do_enhanced_option__ (enhanced, obj) + retval = ""; + if (enhanced) + if (strcmpi (obj.interpreter, "none")) + retval = "noenhanced"; + else + retval = "enhanced"; + endif + endif +endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__go_draw_figure__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,198 @@ +## Copyright (C) 2005-2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} __go_draw_figure__ (@var{h}, @var{plot_stream}, @var{enhanced}, @var{mono}) +## Undocumented internal function. +## @end deftypefn + +## Author: jwe + +function __go_draw_figure__ (h, plot_stream, enhanced, mono) + + if (nargin == 4) + htype = get (h, "type"); + if (strcmp (htype, "figure")) + ## Get complete list of children. + kids = allchild (h); + nkids = length (kids); + + if (nkids > 0) + fputs (plot_stream, "\nreset;\n"); + fputs (plot_stream, "set autoscale keepfix;\n"); + fputs (plot_stream, "set origin 0, 0\n"); + fputs (plot_stream, "set size 1, 1\n"); + bg = get (h, "color"); + if (isnumeric (bg)) + fprintf (plot_stream, "set obj 1 rectangle from screen 0,0 to screen 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * bg); + bg_is_set = true; + else + bg_is_set = false; + endif + + for i = nkids:-1:1 + type = get (kids(i), "type"); + switch (type) + case "axes" + if (strcmpi (get (kids (i), "tag"), "legend")) + ## This is so ugly. If there was a way of getting + ## gnuplot to give us the text extents of strings + ## then we could get rid of this mess. + lh = getfield (get (kids(i), "userdata"), "handle"); + if (isscalar (lh)) + ## We have a legend with a single parent. It'll be handled + ## below as a gnuplot key to the axis it corresponds to + continue; + else + ca = lh(1); + ## Rely upon listener to convert axes position + ## to "normalized" units. + legend_axes_units = get (kids(i), "units"); + legend_axes_position = get (kids(i), "position"); + legend_axes_outerposition = get (kids(i), "outerposition"); + legend_axes_box = get (kids(i), "box"); + legend_axes_ylim = get (kids(i), "ylim"); + orig_axes_units = get (ca, "units"); + hlgnd = get (kids(i)); + + unwind_protect + set (ca, "units", "normalized"); + set (kids(i), "units", "normalized", "box", "off", + "ylim", [-2, -1], "position", get (ca(1), "position"), + "outerposition", get (ca(1), "outerposition")); + + ## Create a new set of lines with the appropriate + ## displaynames, etc + toberm = []; + hobj = get (kids(i), "children"); + for j = numel (hobj) : -1 : 1 + if (! strcmp (get (hobj(j), "type"), "text")) + continue; + endif + displayname = get (hobj(j), "string"); + ll = []; + lm = []; + for k = numel (hobj) : -1 : 1 + if (! strcmp (get (hobj(k), "type"), "line")) + continue; + endif + if (get (hobj(j), "userdata") + != get (hobj(k), "userdata")) + continue; + endif + if (! strcmp (get (hobj(k), "linestyle"), "none")) + ll = hobj(k); + endif + if (! strcmp (get (hobj(k), "marker"), "none")) + lm = hobj(k); + endif + endfor + + if (! isempty (ll)) + if (!isempty (lm)) + toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", get(ll,"linestyle"), "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))]; + else + toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(ll,"color"), "linestyle", get(ll,"linestyle"), "marker", "none", "displayname", displayname, "parent", kids(i))]; + endif + elseif (! isempty (lm)) + toberm = [toberm, line("xdata",[0,0],"ydata",[0,0], "color", get(lm,"color"), "linestyle", "none", "marker", get(lm,"marker"), "markeredgecolor", get(lm,"markeredgecolor"), "markerfacecolor", get(lm,"markerfacecolor"), "markersize", get (lm, "markersize"), "displayname", displayname, "parent", kids(i))]; + endif + endfor + if (bg_is_set) + fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg)); + endif + __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, + bg_is_set, false, hlgnd); + unwind_protect_cleanup + ## Return axes "units" and "position" back to + ## their original values. + set (ca, "units", orig_axes_units); + set (kids(i), "units", legend_axes_units, + "box", legend_axes_box, + "ylim", legend_axes_ylim, + "position", legend_axes_position, + "outerposition", legend_axes_outerposition); + delete (toberm); + bg_is_set = false; + end_unwind_protect + endif + else + ## Rely upon listener to convert axes position + ## to "normalized" units. + orig_axes_units = get (kids(i), "units"); + orig_axes_position = get (kids(i), "position"); + unwind_protect + set (kids(i), "units", "normalized"); + fg = get (kids(i), "color"); + if (isnumeric (fg) && strcmp (get (kids(i), "visible"), "on")) + fprintf (plot_stream, "set obj 2 rectangle from graph 0,0 to graph 1,1 behind fc rgb \"#%02x%02x%02x\"\n", 255 * fg); + fg_is_set = true; + else + fg_is_set = false; + endif + if (bg_is_set) + fprintf (plot_stream, "set border linecolor rgb \"#%02x%02x%02x\"\n", 255 * (1 - bg)); + endif + ## Find if this axes has an associated legend axes and pass it + ## to __go_draw_axes__ + hlegend = []; + fkids = get (h, "children"); + for j = 1 : numel(fkids) + if (ishandle (fkids (j)) + && strcmp (get (fkids (j), "type"), "axes") + && (strcmp (get (fkids (j), "tag"), "legend"))) + udata = get (fkids (j), "userdata"); + if (isscalar(udata.handle) + && ! isempty (intersect (udata.handle, kids (i)))) + hlegend = get (fkids (j)); + break; + endif + endif + endfor + __go_draw_axes__ (kids(i), plot_stream, enhanced, mono, + bg_is_set, fg_is_set, hlegend); + unwind_protect_cleanup + ## Return axes "units" and "position" back to + ## their original values. + set (kids(i), "units", orig_axes_units); + set (kids(i), "position", orig_axes_position); + bg_is_set = false; + fg_is_set = false; + end_unwind_protect + endif + case "uimenu" + ## ignore uimenu objects + otherwise + error ("__go_draw_figure__: unknown object class, %s", type); + endswitch + endfor + fputs (plot_stream, "\nunset multiplot;\n"); + else + fputs (plot_stream, "\nreset; clear;\n"); + fflush (plot_stream); + endif + else + error ("__go_draw_figure__: expecting figure object, found `%s'", + htype); + endif + else + print_usage (); + endif + +endfunction +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__marching_cube__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,530 @@ +## Copyright (C) 2009-2011 Martin Helm +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{t}, @var{p}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}) +## @deftypefnx {Function File} {[@var{t}, @var{p}, @var{c}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col}) +## Undocumented internal function. +## @end deftypefn + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{t}, @var{p}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}) +## @deftypefnx {Function File} {[@var{t}, @var{p}, @var{c}] =} __marching_cube__ (@var{x}, @var{y}, @var{z}, @var{val}, @var{iso}, @var{col}) +## +## Return the triangulation information @var{t} at points @var{p} for +## the isosurface values resp. the volume data @var{val} and the iso +## level @var{iso}. It is considered that the volume data @var{val} is +## given at the points @var{x}, @var{y} and @var{z} which are of type +## three--dimensional numeric arrays. The orientation of the triangles +## is choosen such that the normals point from the higher values to the +## lower values. +## +## Optionally the color data @var{col} can be passed to this function +## whereas computed vertices color data @var{c} is returned as third +## argument. +## +## The marching cube algorithm is well known and described, for example, at +## Wikipedia. The triangulation lookup table and the edge table used +## here are based on Cory Gene Bloyd's implementation and can be found +## beyond other surface and geometry stuff at Paul Bourke's website +## @uref{http://local.wasp.uwa.edu.au/~pbourke/geometry/polygonise}. +## +## For example: +## +## @example +## @group +## N = 20; +## lin = linspace(0, 2, N); +## [x, y, z] = meshgrid (lin, lin, lin); +## +## c = (x-.5).^2 + (y-.5).^2 + (z-.5).^2; +## [t, p] = __marching_cube__ (x, y, z, c, .5); +## +## figure (); +## trimesh (t, p(:,1), p(:,2), p(:,3)); +## @end group +## @end example +## +## Instead of the @command{trimesh} function the @command{patch} +## function can be used to visualize the geometry. For example: +## +## @example +## @group +## figure (); view (-38, 20); +## pa = patch ("Faces", t, "Vertices", p, "FaceVertexCData", p, \ +## "FaceColor", "interp", "EdgeColor", "none"); +## +## ## Revert normals +## set (pa, "VertexNormals", -get(pa, "VertexNormals")); +## +## ## Set lightning (available with the JHandles package) +## # set (pa, "FaceLighting", "gouraud"); +## # light( "Position", [1 1 5]); +## @end group +## @end example +## +## @end deftypefn + +## Author: Martin Helm <martin@mhelm.de> + +function [T, p, col] = __marching_cube__ (xx, yy, zz, c, iso, colors) + + persistent edge_table=[]; + persistent tri_table=[]; + + calc_cols = false; + lindex = 4; + + if (isempty (tri_table) || isempty (edge_table)) + [edge_table, tri_table] = init_mc (); + endif + + if ((nargin != 5 && nargin != 6) || (nargout != 2 && nargout != 3)) + print_usage (); + endif + + if (!ismatrix (xx) || !ismatrix (yy) || !ismatrix (zz) || !ismatrix (c) || ... + ndims (xx) != 3 || ndims (yy) != 3 || ndims (zz) != 3 || ndims (c) != 3) + error ("__marching_cube__: XX, YY, ZZ, C must be matrices of dim 3"); + endif + + if (!size_equal (xx, yy, zz, c)) + error ("__marching_cube__: XX, YY, ZZ, C must be of equal size"); + endif + + if (any (size (xx) < [2 2 2])) + error ("__marching_cube__: grid size must be at least 2x2x2"); + endif + + if (!isscalar (iso)) + error ("__marching_cube__: ISO must be scalar value"); + endif + + if (nargin == 6) + if ( !ismatrix (colors) || ndims (colors) != 3 || size (colors) != size (c) ) + error ( "COLORS must be a matrix of dim 3 and of same size as C" ); + endif + calc_cols = true; + lindex = 5; + endif + + n = size (c) - 1; + + ## phase I: assign information to each voxel which edges are intersected by + ## the isosurface + cc = zeros (n(1), n(2), n(3), "uint16"); + cedge = zeros (size (cc), "uint16"); + + vertex_idx = {1:n(1), 1:n(2), 1:n(3); ... + 2:n(1)+1, 1:n(2), 1:n(3); ... + 2:n(1)+1, 2:n(2)+1, 1:n(3); ... + 1:n(1), 2:n(2)+1, 1:n(3); ... + 1:n(1), 1:n(2), 2:n(3)+1; ... + 2:n(1)+1, 1:n(2), 2:n(3)+1; ... + 2:n(1)+1, 2:n(2)+1, 2:n(3)+1; ... + 1:n(1), 2:n(2)+1, 2:n(3)+1 }; + + ## calculate which vertices have values higher than iso + for ii=1:8 + idx = c(vertex_idx{ii, :}) > iso; + cc(idx) = bitset (cc(idx), ii); + endfor + + cedge = edge_table(cc+1); # assign the info about intersected edges + id = find (cedge); # select only voxels which are intersected + if (isempty (id)) + T = p = col = []; + return + endif + + ## phase II: calculate the list of intersection points + xyz_off = [1, 1, 1; 2, 1, 1; 2, 2, 1; 1, 2, 1; 1, 1, 2; 2, 1, 2; 2, 2, 2; 1, 2, 2]; + edges = [1 2; 2 3; 3 4; 4 1; 5 6; 6 7; 7 8; 8 5; 1 5; 2 6; 3 7; 4 8]; + offset = sub2ind (size (c), xyz_off(:, 1), xyz_off(:, 2), xyz_off(:, 3)) -1; + pp = zeros (length (id), lindex, 12); + ccedge = [vec(cedge(id)), id]; + ix_offset=0; + for jj=1:12 + id__ = bitget (ccedge(:, 1), jj); + id_ = ccedge(id__, 2); + [ix iy iz] = ind2sub (size (cc), id_); + id_c = sub2ind (size (c), ix, iy, iz); + id1 = id_c + offset(edges(jj, 1)); + id2 = id_c + offset(edges(jj, 2)); + if (calc_cols) + pp(id__, 1:5, jj) = [vertex_interp(iso, xx(id1), yy(id1), zz(id1), ... + xx(id2), yy(id2), zz(id2), c(id1), c(id2), colors(id1), colors(id2)), ... + (1:size (id_, 1))' + ix_offset ]; + else + pp(id__, 1:4, jj) = [vertex_interp(iso, xx(id1), yy(id1), zz(id1), ... + xx(id2), yy(id2), zz(id2), c(id1), c(id2)), ... + (1:size (id_, 1))' + ix_offset ]; + endif + ix_offset += size (id_, 1); + endfor + + ## phase III: calculate the triangulation from the point list + T = []; + tri = tri_table(cc(id)+1, :); + for jj=1:3:15 + id_ = find (tri(:, jj)>0); + p = [id_, lindex*ones(size (id_, 1), 1),tri(id_, jj:jj+2)]; + if (!isempty (p)) + p1 = sub2ind (size (pp), p(:,1), p(:,2), p(:,3)); + p2 = sub2ind (size (pp), p(:,1), p(:,2), p(:,4)); + p3 = sub2ind (size (pp), p(:,1), p(:,2), p(:,5)); + T = [T; pp(p1), pp(p2), pp(p3)]; + endif + endfor + + p = []; + col = []; + for jj = 1:12 + idp = pp(:, lindex, jj) > 0; + if (any (idp)) + p(pp(idp, lindex, jj), 1:3) = pp(idp, 1:3, jj); + if (calc_cols) + col(pp(idp, lindex, jj),1) = pp(idp, 4, jj); + endif + endif + endfor +endfunction + +function p = vertex_interp(isolevel,p1x, p1y, p1z,... + p2x, p2y, p2z,valp1,valp2, col1, col2) + + if (nargin == 9) + p = zeros (length (p1x), 3); + elseif (nargin == 11) + p = zeros (length (p1x), 4); + else + error ("__marching_cube__: wrong number of arguments"); + endif + mu = zeros (length (p1x), 1); + id = abs (valp1-valp2) < (10*eps) .* (abs (valp1) .+ abs (valp2)); + if (any (id)) + p(id, 1:3) = [ p1x(id), p1y(id), p1z(id) ]; + if (nargin == 11) + p(id, 4) = col1(id); + endif + endif + nid = !id; + if (any (nid)) + mu(nid) = (isolevel - valp1(nid)) ./ (valp2(nid) - valp1(nid)); + p(nid, 1:3) = [p1x(nid) + mu(nid) .* (p2x(nid) - p1x(nid)), ... + p1y(nid) + mu(nid) .* (p2y(nid) - p1y(nid)), ... + p1z(nid) + mu(nid) .* (p2z(nid) - p1z(nid))]; + if (nargin == 11) + p(nid, 4) = col1(nid) + mu(nid) .* (col2(nid) - col1(nid)); + endif + endif +endfunction + +function [edge_table, tri_table] = init_mc() + edge_table = [ + 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c, ... + 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00, ... + 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c, ... + 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90, ... + 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c, ... + 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30, ... + 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac, ... + 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0, ... + 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c, ... + 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60, ... + 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc, ... + 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0, ... + 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c, ... + 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950, ... + 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc , ... + 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0, ... + 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc, ... + 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0, ... + 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c, ... + 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650, ... + 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc, ... + 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0, ... + 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c, ... + 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460, ... + 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac, ... + 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0, ... + 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c, ... + 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230, ... + 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c, ... + 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190, ... + 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c, ... + 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0 ]; + + tri_table =[ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1; + 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1; + 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1; + 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1; + 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1; + 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1; + 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1; + 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1; + 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1; + 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1; + 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1; + 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1; + 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1; + 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1; + 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1; + 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1; + 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1; + 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1; + 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1; + 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1; + 10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1; + 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1; + 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1; + 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1; + 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1; + 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1; + 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1; + 10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1; + 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1; + 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1; + 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1; + 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1; + 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1; + 11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1; + 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1; + 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1; + 11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1; + 11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1; + 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1; + 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1; + 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1; + 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1; + 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1; + 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1; + 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1; + 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1; + 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1; + 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1; + 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1; + 10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1; + 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1; + 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1; + 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1; + 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1; + 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1; + 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1; + 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1; + 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1; + 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1; + 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1; + 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1; + 10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1; + 10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1; + 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1; + 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1; + 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1; + 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1; + 10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1; + 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1; + 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1; + 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1; + 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1; + 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1; + 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1; + 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1; + 10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1; + 10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1; + 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1; + 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1; + 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1; + 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1; + 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1; + 11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1; + 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1; + 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1; + 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1; + 10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1; + 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1; + 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1; + 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1; + 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1; + 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1; + 10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1; + 10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1; + 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1; + 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1; + 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1; + 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1; + 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1; + 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1; + 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1; + 10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1; + 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1; + 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1; + 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1; + 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1; + 10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1; + 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1; + 10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1; + 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1; + 11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1; + 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1; + 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1; + 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1; + 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1; + 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1; + 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1; + 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1; + 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1; + 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1; + 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1; + 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1; + 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1; + 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1; + 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1; + 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1; + 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1; + 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1; + 11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1; + 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1; + 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1; + 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1; + 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1; + 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1; + 10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1; + 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1; + 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1; + 10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1; + 11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1; + 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1; + 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1; + 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1; + 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1; + 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1; + 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1; + 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1; + 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1; + 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1; + 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1; + 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1; + 10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1; + 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1; + 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1; + 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1; + 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1; + 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1; + 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1; + 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1; + 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1; + 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1; + 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1; + 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1; + 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1; + 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1; + 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1; + 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1; + 11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1; + 11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1; + 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1; + 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1; + 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1; + 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1; + 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1; + 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1; + 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1; + 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1; + 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1; + 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1; + 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1; + 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1; + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 ] + 1; +endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__next_line_color__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,54 @@ +## Copyright (C) 2007-2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{rgb} =} __next_line_color__ (@var{reset}) +## Undocumented internal function. +## @end deftypefn + +## Return the next line color in the rotation. + +## Author: jwe + +function rgb = __next_line_color__ (reset) + + persistent color_rotation; + persistent num_colors; + persistent color_index; + + if (nargin < 2) + if (nargin == 1) + if (reset || isempty (color_rotation)) + color_rotation = get (gca (), "colororder"); + num_colors = rows (color_rotation); + color_index = 1; + endif + elseif (! isempty (color_rotation)) + rgb = color_rotation(color_index,:); + if (++color_index > num_colors) + color_index = 1; + __next_line_style__ ("incr"); + endif + else + error ("__next_line_color__: color_rotation not initialized"); + endif + else + print_usage (); + endif + +endfunction
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__next_line_style__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,58 @@ +## Copyright (C) 2010-2011 David Bateman +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{style} =} __next_line_style__ (@var{reset}) +## Undocumented internal function. +## @end deftypefn + +## Return the next line style in the rotation. + + +function [linestyle, marker] = __next_line_style__ (reset) + + persistent style_rotation; + persistent num_styles; + persistent style_index; + + if (nargin < 2) + if (nargin == 1) + if (ischar (reset) && strncmp (reset, "incr", 4)) + if (isempty (style_rotation)) + error ("__next_line_style__: style_rotation not initialized"); + elseif (++style_index > num_styles) + style_index = 1; + endif + elseif (reset || isempty (style_rotation)) + style_rotation = strsplit (get (gca (), "linestyleorder"), "|"); + num_styles = length (style_rotation); + style_index = 1; + endif + elseif (! isempty (style_rotation)) + options = __pltopt__ ("__next_line_style__", + style_rotation (style_index)); + linestyle = options.linestyle; + marker = options.marker; + else + error ("__next_line_style__: style_rotation not initialized"); + endif + else + print_usage (); + endif + +endfunction
--- a/scripts/plot/private/__patch__.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/private/__patch__.m Fri Aug 12 14:16:34 2011 -0400 @@ -134,7 +134,7 @@ endif else args = varargin; - if (any(cellfun (@(x) strcmpi(x,"faces") || strcmpi(x, "vertices"), args))) + if (any (strcmpi (args, "faces") | strcmpi (args, "vertices"))) args = setdata (args); else args = setvertexdata (args);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/private/__print_parse_opts__.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,610 @@ +## Copyright (C) 2008-2011 David Bateman +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {[@var{x}, @var{y}, @var{buttons}] =} ginput (@var{n}) +## Return which mouse buttons were pressed and keys were hit on the current +## figure. If @var{n} is defined, then wait for @var{n} mouse clicks +## before returning. If @var{n} is not defined, then @code{ginput} will +## loop until the return key is pressed. +## @end deftypefn + +function arg_st = __print_parse_opts__ (varargin) + + persistent warn_on_missing_binary = true + + arg_st.append_to_file = false; + arg_st.canvas_size = []; + arg_st.debug = false; + arg_st.debug_file = "octave-print-commands.log"; + arg_st.devopt = ""; + arg_st.epstool_binary = __quote_path__ (__find_binary__ ("epstool")); + arg_st.figure = get (0, "currentfigure"); + arg_st.fig2dev_binary = __quote_path__ (__find_binary__ ("fig2dev")); + arg_st.fontsize = ""; + arg_st.font = ""; + arg_st.force_solid = 0; # 0=default, -1=dashed, +1=solid + arg_st.formatted_for_printing = false; + arg_st.ghostscript.binary = __quote_path__ (__ghostscript_binary__ ()); + arg_st.ghostscript.debug = false; + arg_st.ghostscript.device = ""; + arg_st.ghostscript.epscrop = true; + arg_st.ghostscript.level = []; + arg_st.ghostscript.output = ""; + arg_st.ghostscript.papersize = ""; + arg_st.ghostscript.pageoffset = []; + arg_st.ghostscript.resolution = 150; + arg_st.ghostscript.antialiasing = false; + arg_st.loose = false; + arg_st.lpr_binary = __quote_path__ (__find_binary__ ("lpr")); + arg_st.name = ""; + arg_st.orientation = ""; + arg_st.pstoedit_binary = __quote_path__ (__find_binary__ ("pstoedit")); + arg_st.preview = ""; + arg_st.printer = ""; + arg_st.send_to_printer = false; + arg_st.special_flag = "textnormal"; + arg_st.tight_flag = false; + arg_st.use_color = 0; # 0=default, -1=mono, +1=color + + if (isunix ()) + arg_st.lpr_options = "-l"; + elseif (ispc ()) + arg_st.lpr_options = "-o l"; + else + arg_st.lpr_options = ""; + endif + arg_st.unlink = {}; + + if (nargin > 0 && isfigure (varargin{1})) + arg_st.figure = varargin{1}; + varargin(1) = []; + endif + + for i = 1:numel(varargin) + arg = strtrim (varargin{i}); + if (ischar (arg)) + if (strcmp (arg, "-color")) + arg_st.use_color = 1; + elseif (strcmp (arg, "-append")) + arg_st.append_to_file = true; + elseif (strcmp (arg, "-mono")) + arg_st.use_color = -1; + elseif (strcmp (arg, "-solid")) + arg_st.force_solid = 1; + elseif (strcmp (arg, "-dashed")) + arg_st.force_solid = -1; + elseif (strncmp (arg, "-portrait", numel (arg))) + arg_st.orientation = "portrait"; + elseif (strncmp (arg, "-landscape", numel (arg))) + arg_st.orientation = "landscape"; + elseif (strcmp (arg, "-loose")) + arg_st.loose = true; + arg_st.tight_flag = false; + elseif (strcmp (arg, "-tight")) + arg_st.loose = false; + arg_st.tight_flag = true; + elseif (strcmp (arg, "-textspecial")) + arg_st.special_flag = "textspecial"; + elseif (any (strcmp (arg, {"-interchange", "-metafile", "-pict", "-tiff"}))) + arg_st.preview = arg(2:end); + elseif (strncmp (arg, "-debug", 6)) + arg_st.debug = true; + arg_st.ghostscript.debug = true; + if (length (arg) > 7) + arg_st.debug_file = arg(8:end); + endif + elseif (length (arg) > 2 && arg(1:2) == "-d") + arg_st.devopt = tolower (arg(3:end)); + elseif (length (arg) > 2 && arg(1:2) == "-P") + arg_st.printer = arg; + elseif (strncmp (arg, "-EPSTOOL:", 9)) + arg_st.epstool_binary = arg{10:end}; + elseif (strncmp (arg, "-FIG2DEV:", 9)) + arg_st.fig2dev_binary = arg{10:end}; + elseif (strncmp (arg, "-PSTOEDIT:", 9)) + arg_st.pstoedit_binary = arg{10:end}; + elseif ((length (arg) > 2) && arg(1:2) == "-G") + arg_st.ghostscript.binary = file_in_path (getenv ("PATH"), arg(3:end)); + if (isempty (arg_st.ghostscript.binary)) + error ("print: Ghostscript binary ""%s"" could not be located", + arg(3:end)); + else + arg_st.ghostscript_binary = __quote_path__ (arg_st.ghostscript_binary); + endif + elseif (length (arg) > 2 && arg(1:2) == "-F") + idx = rindex (arg, ":"); + if (idx) + arg_st.font = arg(3:idx-1); + arg_st.fontsize = str2num (arg(idx+1:end)); + else + arg_st.font = arg(3:end); + endif + elseif (length (arg) > 2 && arg(1:2) == "-S") + arg_st.canvas_size = str2num (arg(3:end)); + elseif (length (arg) > 2 && arg(1:2) == "-r") + arg_st.ghostscript.resolution = str2double (arg(3:end)); + elseif (length (arg) > 2 && arg(1:2) == "-f") + arg_st.figure = str2num (arg(3:end)); + elseif (length (arg) >= 1 && arg(1) == "-") + error ("print: unknown option `%s'", arg); + elseif (length (arg) > 0) + arg_st.name = arg; + endif + elseif (isfigure (arg)) + arg_st.figure = arg; + else + error ("print: expecting inputs to be character string options or a figure handle"); + endif + endfor + + if (arg_st.ghostscript.resolution == 0) + ## Do as Matlab does. + arg_st.ghostscript.resolution = num2str (get (0, "screenpixelsperinch")); + endif + + if (isempty (arg_st.orientation)) + if (isfigure (arg_st.figure)) + arg_st.orientation = get (arg_st.figure, "paperorientation"); + else + ## Allows tests to be run without error. + arg_st.orientation = "portrait"; + endif + endif + + if (isempty (arg_st.ghostscript.binary)) + arg_st.ghostscript.binary = __ghostscript_binary__ (); + endif + + dot = rindex (arg_st.name, "."); + if (isempty (arg_st.devopt)) + if (dot == 0) + arg_st.devopt = "psc"; + else + arg_st.devopt = tolower (arg_st.name(dot+1:end)); + endif + endif + + if (arg_st.use_color == 0) + if (any (strcmp ({"ps", "ps2", "eps", "eps2"}, arg_st.devopt))) + arg_st.use_color = -1; + else + arg_st.use_color = 1; + endif + endif + + if (strcmp (arg_st.devopt, "tex")) + arg_st.devopt = "epslatex"; + elseif (strcmp (arg_st.devopt, "ill")) + arg_st.devopt = "aifm"; + elseif (strcmp (arg_st.devopt, "cdr")) + arg_st.devopt = "corel"; + elseif (strcmp (arg_st.devopt, "meta")) + arg_st.devopt = "emf"; + elseif (strcmp (arg_st.devopt, "jpg")) + arg_st.devopt = "jpeg"; + endif + + dev_list = {"aifm", "corel", "fig", "png", "jpeg", ... + "gif", "pbm", "pbmraw", "dxf", "mf", ... + "svg", "hpgl", "ps", "ps2", "psc", ... + "psc2", "eps", "eps2", "epsc", "epsc2", ... + "emf", "pdf", "pslatex", "epslatex", "epslatexstandalone", ... + "pslatexstandalone", "pdflatexstandalone", ... + "pstex", "tiff", "tiffn" "tikz", "pcxmono", ... + "pcx24b", "pcx256", "pcx16", "pgm", "pgmraw", ... + "ppm", "ppmraw", "pdflatex", "texdraw", ... + "pdfcairo", "pngcairo", "pstricks", ... + "epswrite", "pswrite", "ps2write", "pdfwrite"}; + + suffixes = {"ai", "cdr", "fig", "png", "jpg", ... + "gif", "pbm", "pbm", "dxf", "mf", ... + "svg", "hpgl", "ps", "ps", "ps", ... + "ps", "eps", "eps", "eps", "eps", ... + "emf", "pdf", "tex", "tex", "tex", ... + "tex", "tex", ... + "ps", "tiff", "tiff", "tikz", "pcx", ... + "pcx", "pcx", "pcx", "pgm", "pgm", ... + "ppm", "ppm", "tex", "tex", ... + "pdf", "png", "tex", ... + "eps", "ps", "ps", "pdf"}; + + if (isfigure (arg_st.figure)) + __graphics_toolkit__ = get (arg_st.figure, "__graphics_toolkit__"); + else + ## Allow tests when no figures are present. + __graphics_toolkit__ = get (0, "defaultfigure__graphics_toolkit__"); + endif + + if (strcmp (__graphics_toolkit__, "gnuplot") + && __gnuplot_has_feature__ ("epslatex_implies_eps_filesuffix")) + suffixes(strncmp (dev_list, "epslatex", 8)) = {"eps"}; + endif + + match = strcmpi (dev_list, arg_st.devopt); + if (any (match)) + default_suffix = suffixes {match}; + else + default_suffix = arg_st.devopt; + endif + + if (dot == 0 && ! isempty (arg_st.name)) + arg_st.name = strcat (arg_st.name, ".", default_suffix); + endif + + if (arg_st.append_to_file) + if (isempty (arg_st.name)) + arg_st.append_to_file = false; + elseif (any (strcmpi (arg_st.devopt, {"eps", "eps2", "epsc", "epsc2", ... + "ps", "ps2", "psc", "psc2", "pdf"}))) + have_ghostscript = ! isempty (__ghostscript_binary__ ()); + if (have_ghostscript) + file_exists = ((numel (dir (arg_st.name)) == 1) + && (! isdir (arg_st.name))); + if (! file_exists) + arg_st.append_to_file = false; + endif + else + arg_st.append_to_file = false; + warning ("print.m: appended output requires ghostscript to be installed"); + endif + else + warning ("print.m: appended output is not supported for device '%s'", + arg_st.devopt); + arg_st.append_to_file = false; + endif + endif + + if (! isempty (arg_st.printer) || isempty (arg_st.name)) + arg_st.send_to_printer = true; + endif + + if (any (strcmp (arg_st.devopt, {"ps", "ps2", "psc", "psc2", "pdf"}))) + arg_st.formatted_for_printing = true; + endif + + aliases = gs_aliases (); + if (any (strcmp (arg_st.devopt, fieldnames (aliases)))) + arg_st.devopt = aliases.(arg_st.devopt); + endif + + ## FIXME - eps2 & epsc2 needs to be handled + if (strcmp (arg_st.devopt, "pswrite")) + arg_st.ghostscript.level = 1; + elseif (strcmp (arg_st.devopt, "ps2write")) + arg_st.ghostscript.level = 2; + endif + + if ((any (strcmp (arg_st.devopt, gs_device_list)) + && ! arg_st.formatted_for_printing) + || any (strcmp (arg_st.devopt, {"pswrite", "ps2write", "pdfwrite"}))) + ## Use ghostscript for graphic formats + arg_st.ghostscript.device = arg_st.devopt; + arg_st.ghostscript.output = arg_st.name; + arg_st.ghostscript.antialiasing = true; + if (arg_st.formatted_for_printing) + arg_st.ghostscript.epscrop = ! arg_st.loose; + else + ## pstoedit throws errors if the EPS file isn't cropped + arg_st.ghostscript.epscrop = true; + endif + elseif (all (! strcmp (arg_st.devopt, dev_list))) + ## Assume we are formating output for a printer + arg_st.formatted_for_printing = true; + arg_st.ghostscript.device = arg_st.devopt; + arg_st.ghostscript.output = arg_st.name; + arg_st.ghostscript.antialiasing = false; + arg_st.ghostscript.epscrop = ! arg_st.loose; + endif + + if (isempty (arg_st.canvas_size)) + if (isfigure (arg_st.figure)) + [arg_st.ghostscript.papersize, paperposition] = ... + gs_papersize (arg_st.figure, arg_st.orientation); + else + ## allows tests to be run + arg_st.ghostscript.papersize = "letter"; + paperposition = [0.25, 2.50, 8.00, 6.00] * 72; + endif + arg_st.canvas_size = paperposition(3:4); + if (strcmp (__graphics_toolkit__, "gnuplot") && ! arg_st.ghostscript.epscrop) + arg_st.ghostscript.pageoffset = paperposition(1:2) - 50; + else + arg_st.ghostscript.pageoffset = paperposition(1:2); + endif + else + ## Convert canvas size to points from pixles. + arg_st.canvas_size = arg_st.canvas_size * 72 / arg_st.ghostscript.resolution; + arg_st.ghostscript.papersize = arg_st.canvas_size; + arg_st.ghostscript.epscrop = true; + arg_st.ghostscript.pageoffset = [0, 0]; + endif + + if (arg_st.formatted_for_printing) + arg_st.ghostscript.resolution = []; + else + arg_st.ghostscript.papersize = ""; + arg_st.ghostscript.pageoffset = [0, 0]; + endif + + if (warn_on_missing_binary) + if (isempty (arg_st.ghostscript.binary)) + warning ("print:missing_gs", "print.m: Ghostscript binary is not available.\nOnly eps output is available."); + else + if (isempty (arg_st.epstool_binary)) + warning ("print:missing_epstool", "print.m: epstool binary is not available.\nSome output formats are not available."); + endif + if (isempty (arg_st.fig2dev_binary)) + warning ("print:missing_fig2dev", "print.m: fig2dev binary is not available.\nSome output formats are not available."); + endif + if (isempty (arg_st.pstoedit_binary)) + warning ("print:missing_pstoedit", "print.m: pstoedit binary is not available.\nSome output formats are not available."); + endif + endif + warn_on_missing_binary = false; + endif + +endfunction + +## Test blocks are not allowed (and not needed) for private functions +#%!test +%! opts = __print_parse_opts__ (); +%! assert (opts.devopt, "pswrite"); +%! assert (opts.use_color, 1); +%! assert (opts.send_to_printer, true); +%! assert (opts.canvas_size, [576, 432]); +%! assert (opts.ghostscript.device, "pswrite") + +#%!test +%! opts = __print_parse_opts__ ("test.pdf", "-S640,480"); +%! assert (opts.canvas_size, [307.2, 230.4], 0.1); + +#%!test +%! opts = __print_parse_opts__ ("-dpsc", "-append", "-loose"); +%! assert (opts.devopt, "pswrite"); +%! assert (opts.send_to_printer, true); +%! assert (opts.use_color, 1); +%! assert (opts.append_to_file, false); +%! assert (opts.ghostscript.device, "pswrite") +%! assert (opts.ghostscript.epscrop, false); + +#%!test +%! opts = __print_parse_opts__ ("-deps", "-tight"); +%! assert (opts.tight_flag, true); +%! assert (opts.send_to_printer, true); +%! assert (opts.use_color, -1); +%! assert (opts.ghostscript.device, "") + +#%!test +%! opts = __print_parse_opts__ ("-djpg", "foobar", "-mono", "-loose"); +%! assert (opts.devopt, "jpeg") +%! assert (opts.name, "foobar.jpg") +%! assert (opts.ghostscript.device, "jpeg") +%! assert (opts.ghostscript.epscrop, true); +%! assert (opts.ghostscript.papersize, ""); +%! assert (opts.ghostscript.pageoffset, [0, 0]); +%! assert (opts.send_to_printer, false); +%! assert (opts.printer, ""); +%! assert (opts.use_color, -1); + +#%!test +%! opts = __print_parse_opts__ ("-ddeskjet", "foobar", "-mono", "-Pmyprinter"); +%! assert (opts.ghostscript.output, "foobar.deskjet") +%! assert (opts.ghostscript.device, "deskjet") +%! assert (opts.devopt, "deskjet") +%! assert (opts.send_to_printer, true); +%! assert (opts.printer, "-Pmyprinter"); +%! assert (opts.use_color, -1); + +#%!test +%! opts = __print_parse_opts__ ("-f5", "-dljet3"); +%! assert (opts.ghostscript.device, "ljet3") +%! assert (strfind (opts.ghostscript.output, ".ljet3")) +%! assert (opts.devopt, "ljet3") +%! assert (opts.send_to_printer, true); +%! assert (opts.figure, 5) + +function cmd = __quote_path__ (cmd) + if (any (cmd == " ") && ! (cmd(1) == """" && cmd(end) == """")) + cmd = strcat ("""", strrep (cmd, """", """"""), """"); + endif +endfunction + +function gs = __ghostscript_binary__ () + + persistent ghostscript_binary = "" + persistent warn_on_no_ghostscript = true + persistent warn_on_bad_gsc = true + + if (isempty (ghostscript_binary)) + GSC = getenv ("GSC"); + if (exist (GSC, "file") + || (! isempty (GSC) && file_in_path (getenv ("PATH"), GSC))) + gs_binaries = {GSC}; + elseif (! isempty (GSC) && warn_on_bad_gsc) + warning ("print:badgscenv", + "print.m: GSC environment variable not set properly"); + warn_on_bad_gsc = false; + gs_binaries = {}; + else + gs_binaries = {}; + endif + if (isunix ()) + ## Unix - Includes Mac OSX and Cygwin. + gs_binaries = horzcat (gs_binaries, {"gs", "gs.exe"}); + else + ## pc - Includes Win32 and mingw. + gs_binaries = horzcat (gs_binaries, {"gs.exe", "gswin32c.exe"}); + endif + n = 0; + while (n < numel (gs_binaries) && isempty (ghostscript_binary)) + n = n + 1; + ghostscript_binary = file_in_path (getenv ("PATH"), gs_binaries{n}); + endwhile + if (warn_on_no_ghostscript && isempty (ghostscript_binary)) + warning ("print:noghostscript", + "print.m: ghostscript not found in PATH"); + warn_on_no_ghostscript = false; + endif + endif + + gs = ghostscript_binary; + +endfunction + +function bin = __find_binary__ (binary) + + persistent data = struct () + + if (! isfield (data, binary)) + ## Reinitialize when `user_binaries' is present. + data.(binary).bin = ""; + data.(binary).warn_on_absence = false; + endif + + if (isempty (data.(binary).bin)) + if (isunix ()) + ## Unix - Includes Mac OSX and Cygwin. + binaries = strcat (binary, {"", ".exe"}); + else + ## pc - Includes Win32 and mingw. + binaries = strcat (binary, {".exe"}); + endif + n = 0; + while (n < numel (binaries) && isempty (data.(binary).bin)) + n = n + 1; + data.(binary).bin = file_in_path (getenv ("PATH"), binaries{n}); + endwhile + if (isempty (data.(binary).bin) && data.(binary).warn_on_absence) + warning (sprintf ("print:no%s", binary), + "print.m: '%s' not found in PATH", binary); + data.(binary).warn_on_absence = false; + endif + endif + + bin = data.(binary).bin; + +endfunction + +function [papersize, paperposition] = gs_papersize (hfig, paperorientation) + persistent papertypes papersizes + + if (isempty (papertypes)) + papertypes = {"usletter", "uslegal", "a0", "a1", ... + "a2", "a3", "a4", "a5", ... + "b0", "b1", "b2", "b3", ... + "b4", "b5", "arch-a", "arch-b", ... + "arch-c", "arch-d", "arch-e", "a", ... + "b", "c", "d", "e", ... + "tabloid"}; + papersizes = [ 8.5, 11.0; 8.5, 14.0; 33.1, 46.8; 23.4, 33.1; + 16.5, 23.4; 11.7, 16.5; 8.3, 11.7; 5.8, 8.3; + 39.4, 55.7; 27.8, 39.4; 19.7, 27.8; 13.9, 19.7; + 9.8, 13.9; 6.9, 9.8; 9.0, 12.0; 12.0, 18.0; + 18.0, 24.0; 24.0, 36.0; 36.0, 48.0; 8.5, 11.0; + 11.0, 17.0; 18.0, 24.0; 24.0, 36.0; 36.0, 48.0; + 11.0, 17.0] * 72; + endif + + papertype = get (hfig, "papertype"); + paperunits = get (hfig, "paperunits"); + paperposition = get (hfig, "paperposition"); + if (strcmp (papertype, "<custom>")) + papersize = get (hfig, "papersize"); + papersize = convert2points (papersize , paperunits); + else + papersize = papersizes (strcmp (papertypes, papertype), :); + endif + + if (strcmp (paperunits, "normalized")) + paperposition = paperposition .* papersize([1,2,1,2]); + else + paperposition = convert2points (paperposition, paperunits); + endif + + ## FIXME - This will be obsoleted by listeners for paper properties. + ## Papersize is tall when portrait,and wide when landscape. + if ((papersize(1) > papersize(2) && strcmpi (paperorientation, "portrait")) + || (papersize(1) < papersize(2) && strcmpi (paperorientation, "landscape"))) + papersize = papersize ([2,1]); + paperposition = paperposition([2,1,4,3]); + endif + + if ((! strcmp (papertype, "<custom>")) && (strcmp (paperorientation, "portrait"))) + ## For portrait use the ghostscript name + papersize = papertype; + papersize(papersize=="-") = ""; + papersize = strrep (papersize, "us", ""); + switch (papersize) + case "a" + papersize = "letter"; + case {"b", "tabloid"} + papersize = "11x17"; + case {"c", "d", "e"} + papersize = strcat ("arch", papersize); + endswitch + if (strncmp (papersize, "arch", 4)) + papersize(end) = upper (papersize(end)); + endif + endif + +endfunction + +function value = convert2points (value, units) + switch (units) + case "inches" + value = value * 72; + case "centimeters" + value = value * 72 / 25.4; + case "normalized" + error ("print:customnormalized", + "print.m: papersize=='<custom>' and paperunits='normalized' may not be combined"); + endswitch +endfunction + +function device_list = gs_device_list (); + ## Graphics formats/languages, not priners. + device_list = {"bmp16"; "bmp16m"; "bmp256"; "bmp32b"; "bmpgray"; ... + "epswrite"; "jpeg"; "jpegcymk"; "jpeggray"; "pbm"; ... + "pbmraw"; "pcx16"; "pcx24b"; "pcx256"; "pcx2up"; ... + "pcxcmyk"; "pcxgray"; "pcxmono"; "pdfwrite"; "pgm"; ... + "pgmraw"; "pgnm"; "pgnmraw"; "png16"; "png16m"; ... + "png256"; "png48"; "pngalpha"; "pnggray"; "pngmono"; ... + "pnm"; "pnmraw"; "ppm"; "ppmraw"; "ps2write"; ... + "pswrite"; "tiff12nc"; "tiff24nc"; "tiff32nc"; ... + "tiffcrle"; "tiffg3"; "tiffg32d"; "tiffg4"; ... + "tiffgray"; "tifflzw"; "tiffpack"; "tiffsep"}; +endfunction + +function aliases = gs_aliases (); + ## Aliases for other devices: "bmp", "png", "tiff", "tiffn", "pdf", + ## "ps", "ps2", "psc", "psc2" + ## + ## eps, epsc, eps2, epsc2 are not included here because those are + ## are generated by the graphics toolkit. + aliases.bmp = "bmp32b"; + aliases.pdf = "pdfwrite"; + aliases.png = "png16m"; + aliases.ps = "pswrite"; + aliases.ps2 = "ps2write"; + aliases.psc = "pswrite"; + aliases.psc2 = "ps2write"; + aliases.tiff = "tiff24nc"; + aliases.tiffn = "tiff24nc"; +endfunction +
--- a/scripts/plot/rectangle.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/rectangle.m Fri Aug 12 14:16:34 2011 -0400 @@ -25,8 +25,8 @@ ## @deftypefnx {Function File} {@var{h} =} rectangle (@dots{}) ## ## Draw rectangular patch defined by @var{pos} and @var{curv}. The variable -## @code{@var{pos}(1 : 2)} defines the lower left-hand corner of the patch -## and @code{@var{pos}(3 : 4)} defines its width and height. By default, the +## @code{@var{pos}(1:2)} defines the lower left-hand corner of the patch +## and @code{@var{pos}(3:4)} defines its width and height. By default, the ## value of @var{pos} is @code{[0, 0, 1, 1]}. ## ## The variable @var{curv} defines the curvature of the sides of the rectangle @@ -41,7 +41,7 @@ ## by ## ## @example -## min (pos (1: 2)) / max (pos (1:2)) * curv +## min (pos (1:2)) / max (pos (1:2)) * curv ## @end example ## ## Other properties are passed to the underlying patch command. If called
--- a/scripts/plot/refreshdata.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/refreshdata.m Fri Aug 12 14:16:34 2011 -0400 @@ -83,7 +83,7 @@ obj = get (h (i)); fldnames = fieldnames (obj); m = regexpi (fieldnames(obj), '^.+datasource$', "match"); - idx = cellfun (@(x) !isempty(x), m); + idx = ! cellfun ("isempty", m); if (any (idx)) tmp = m(idx); props = [props; {vertcat(tmp{:})}];
--- a/scripts/plot/subplot.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/subplot.m Fri Aug 12 14:16:34 2011 -0400 @@ -124,7 +124,22 @@ units = "normalized"; set (0, "defaultaxesunits", units); set (cf, "units", "pixels"); - pos = subplot_position (rows, cols, index, "position"); + + ## FIXME: At the moment we force gnuplot to use the aligned mode + ## which will set "activepositionproperty" to "position". + ## Τhis can yield to text overlap between labels and titles + ## see bug #31610 + if (strcmp (get (cf, "__graphics_toolkit__"), "gnuplot")) + align_axes = true; + endif + + if (align_axes) + pos = subplot_position (rows, cols, index, "position"); + elseif (strcmp (get (cf, "__graphics_toolkit__"), "gnuplot")) + pos = subplot_position (rows, cols, index, "outerpositiontight"); + else + pos = subplot_position (rows, cols, index, "outerposition"); + endif set (cf, "nextplot", "add"); @@ -144,7 +159,11 @@ || strcmp (get (child, "tag"), "colorbar")) continue; endif - objpos = get (child, "position"); + if (align_axes) + objpos = get (child, "position"); + else + objpos = get (child, "outerposition"); + endif if (all (objpos == pos) && ! replace_axes) ## If the new axes are in exactly the same position as an ## existing axes object, use the existing axes. @@ -170,14 +189,13 @@ if (found) set (cf, "currentaxes", tmp); + elseif (align_axes) + tmp = axes ("box", "off", "position", pos); + elseif (strcmp (get (cf, "__graphics_toolkit__"), "gnuplot")) + tmp = axes ("box", "off", "outerposition", pos); else - outpos = subplot_position (rows, cols, index, "outerposition"); - tmp = axes ("looseinset", [0 0 0 0], "box", "off", - "outerposition", outpos, "position", pos); - endif - - if (align_axes || strcmp (get (cf, "__graphics_toolkit__"), "gnuplot")) - set (tmp, "activepositionproperty", "position"); + tmp = axes ("looseinset", [0 0 0 0], "box", "off", "outerposition", pos, + "autopos_tag", "subplot"); endif unwind_protect_cleanup @@ -193,67 +211,55 @@ function pos = subplot_position (rows, cols, index, position_property) - defaultaxesposition = get (0, "defaultaxesposition"); - defaultaxesouterposition = get (0, "defaultaxesouterposition"); - if (rows == 1 && cols == 1) ## Trivial result for subplot (1,1,1) if (strcmpi (position_property, "position")) - pos = defaultaxesposition; + pos = get (0, "defaultaxesposition"); else - pos = defaultaxesouterposition; + pos = get (0, "defaultaxesouterposition"); endif return endif - ## The outer margins surrounding all subplot "positions" are independent of - ## the number of rows and/or columns - margins.left = defaultaxesposition(1); - margins.bottom = defaultaxesposition(2); - margins.right = 1.0 - margins.left - defaultaxesposition(3); - margins.top = 1.0 - margins.bottom - defaultaxesposition(4); - - ## Fit from Matlab experiments - pc = 1 ./ [0.1860, (margins.left + margins.right - 1)]; - margins.column = 1 ./ polyval (pc , cols); - pr = 1 ./ [0.2282, (margins.top + margins.bottom - 1)]; - margins.row = 1 ./ polyval (pr , rows); - - ## Calculate the width/height of the subplot axes "position". - ## This is also consistent with Matlab - width = 1 - margins.left - margins.right - (cols-1)*margins.column; - width = width / cols; - height = 1 - margins.top - margins.bottom - (rows-1)*margins.row; - height = height / rows; + if (strcmp (position_property, "outerposition") + || strcmp (position_property, "outerpositiontight")) + margins.left = 0.05; + margins.bottom = 0.05; + margins.right = 0.05; + margins.top = 0.05; + if (strcmp (position_property, "outerpositiontight")) + margins.column = 0.; + margins.row = 0.; + else + margins.column = 0.04 / cols; + margins.row = 0.04 / rows; + endif + width = 1 - margins.left - margins.right - (cols-1)*margins.column; + width = width / cols; + height = 1 - margins.top - margins.bottom - (rows-1)*margins.row; + height = height / rows; + else + defaultaxesposition = get (0, "defaultaxesposition"); - if (strcmp (position_property, "outerposition") ) - ## Calculate the inset of the position relative to the outerposition - ## The outerpositions are assumed to be tiled. Matlab's implementation - ## has outerposition overlap. - if (rows > 1) - ## Title on top and xlabel & xticks on bottom - inset.top = margins.row * (1/3); - inset.bottom = margins.row * (2/3); - ## Matlab behavior is approximately ... - % inset.bottom = margins.row; - else - inset.bottom = margins.bottom; - inset.top = margins.top; - endif - if (cols > 1) - ## ylabel & yticks on left and some overhang for xticks on right - x = 0.1; - inset.right = x * margins.column; - inset.left = (1 - x) * margins.column; - else - inset.left = margins.left; - inset.right = margins.right; - endif - ## Apply the inset to the geometries for the "position" property. - margins.column = margins.column - inset.right - inset.left; - margins.row = margins.row - inset.top - inset.bottom; - width = width + inset.right + inset.left; - height = height + inset.top + inset.bottom; + ## The outer margins surrounding all subplot "positions" are independent + ## of the number of rows and/or columns + margins.left = defaultaxesposition(1); + margins.bottom = defaultaxesposition(2); + margins.right = 1.0 - margins.left - defaultaxesposition(3); + margins.top = 1.0 - margins.bottom - defaultaxesposition(4); + + ## Fit from Matlab experiments + pc = 1 ./ [0.1860, (margins.left + margins.right - 1)]; + margins.column = 1 ./ polyval (pc , cols); + pr = 1 ./ [0.2282, (margins.top + margins.bottom - 1)]; + margins.row = 1 ./ polyval (pr , rows); + + ## Calculate the width/height of the subplot axes "position". + ## This is also consistent with Matlab + width = 1 - margins.left - margins.right - (cols-1)*margins.column; + width = width / cols; + height = 1 - margins.top - margins.bottom - (rows-1)*margins.row; + height = height / rows; endif ## Index offsets from the lower left subplot @@ -265,12 +271,6 @@ x0 = xi .* (width + margins.column) + margins.left; y0 = yi .* (height + margins.row) + margins.bottom; - if (strcmp (position_property, "outerposition") ) - ## Shift from position(1:2) to outerposition(1:2) - x0 = x0 - inset.left; - y0 = y0 - inset.bottom; - endif - if (numel(x0) > 1) ## subplot (row, col, m:n) x1 = max (x0(:)) + width;
--- a/scripts/plot/surface.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/surface.m Fri Aug 12 14:16:34 2011 -0400 @@ -155,3 +155,7 @@ endif endfunction + +## Mark file as being tested. Tests for surface are in +## surf.m, surfc.m, surfl.m, and pcolor.m +%!assert(1)
--- a/scripts/plot/surfc.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/surfc.m Fri Aug 12 14:16:34 2011 -0400 @@ -45,7 +45,26 @@ drawnow (); zmin = get (ax, "zlim")(1); - [c, tmp2] = __contour__ (ax, zmin, varargin{:}); + # don't pass axis handle and/or string arguments to __contour__() + stop_idx = nargin; + for i = 2 : nargin + if (ischar (varargin{i})) + stop_idx = i - 1; + break; + endif + endfor + + start_idx = 1; + if (ishandle (varargin{1})) + start_idx = 2; + endif + + if (stop_idx - start_idx == 1 || stop_idx - start_idx == 3) + #don't pass a color matrix c to __contour__ + stop_idx -= 1; + endif + + [c, tmp2] = __contour__ (ax, zmin, varargin{start_idx:stop_idx}); tmp = [tmp; tmp2];
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/trimesh.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,66 @@ +## Copyright (C) 2007-2011 David Bateman +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} trimesh (@var{tri}, @var{x}, @var{y}, @var{z}) +## @deftypefnx {Function File} {@var{h} =} trimesh (@dots{}) +## Plot a triangular mesh in 3D@. The variable @var{tri} is the triangular +## meshing of the points @code{(@var{x}, @var{y})} which is returned +## from @code{delaunay}. The variable @var{z} is value at the point +## @code{(@var{x}, @var{y})}. The output argument @var{h} is the graphic +## handle of the plot. +## @seealso{triplot, trisurf, delaunay3} +## @end deftypefn + +function h = trimesh (tri, x, y, z, varargin) + + if (nargin < 3) + print_usage (); + endif + + if (nargin == 3) + triplot (tri, x, y); + elseif (ischar (z)) + triplot (tri, x, y, z, varargin{:}); + else + newplot (); + if (nargout > 0) + h = patch ("Vertices", [x(:), y(:), z(:)], "Faces", tri, + "FaceColor", "none", "EdgeColor", __next_line_color__(), + varargin{:}); + else + patch ("Vertices", [x(:), y(:), z(:)], "Faces", tri, + "FaceColor", "none", "EdgeColor", __next_line_color__(), + varargin{:}); + endif + + if (! ishold ()) + set (gca(), "view", [-37.5, 30], + "xgrid", "on", "ygrid", "on", "zgrid", "on"); + endif + endif +endfunction + +%!demo +%! N = 10; +%! rand ('state', 10) +%! x = 3 - 6 * rand (N, N); +%! y = 3 - 6 * rand (N, N); +%! z = peaks (x, y); +%! tri = delaunay (x(:), y(:)); +%! trimesh (tri, x(:), y(:), z(:));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/triplot.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,53 @@ +## Copyright (C) 2007-2011 David Bateman +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} triplot (@var{tri}, @var{x}, @var{y}) +## @deftypefnx {Function File} {} triplot (@var{tri}, @var{x}, @var{y}, @var{linespec}) +## @deftypefnx {Function File} {@var{h} =} triplot (@dots{}) +## Plot a triangular mesh in 2D@. The variable @var{tri} is the triangular +## meshing of the points @code{(@var{x}, @var{y})} which is returned from +## @code{delaunay}. If given, the @var{linespec} determines the properties +## to use for the lines. The output argument @var{h} is the graphic handle +## of the plot. +## @seealso{plot, trimesh, trisurf, delaunay} +## @end deftypefn + +function h = triplot (tri, x, y, varargin) + + if (nargin < 3) + print_usage (); + endif + + idx = tri(:, [1, 2, 3, 1]).'; + nt = size (tri, 1); + if (nargout > 0) + h = plot ([x(idx); NaN(1, nt)](:), + [y(idx); NaN(1, nt)](:), varargin{:}); + else + plot ([x(idx); NaN(1, nt)](:), + [y(idx); NaN(1, nt)](:), varargin{:}); + endif +endfunction + +%!demo +%! rand ('state', 2) +%! x = rand (20, 1); +%! y = rand (20, 1); +%! tri = delaunay (x, y); +%! triplot (tri, x, y);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/plot/trisurf.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,102 @@ +## Copyright (C) 2007-2011 David Bateman +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} trisurf (@var{tri}, @var{x}, @var{y}, @var{z}) +## @deftypefnx {Function File} {@var{h} =} trisurf (@dots{}) +## Plot a triangular surface in 3D@. The variable @var{tri} is the triangular +## meshing of the points @code{(@var{x}, @var{y})} which is returned +## from @code{delaunay}. The variable @var{z} is value at the point +## @code{(@var{x}, @var{y})}. The output argument @var{h} is the graphic +## handle of the plot. +## @seealso{triplot, trimesh, delaunay3} +## @end deftypefn + +function varargout = trisurf (tri, x, y, z, varargin) + + if (nargin < 3) + print_usage (); + endif + + if (nargin == 3) + triplot (tri, x, y); + elseif (ischar (z)) + triplot (tri, x, y, z, varargin{:}); + else + if (nargin > 4 && isnumeric (varargin{1})) + c = varargin{1}; + varargin(1) = []; + else + c = z; + endif + if (! any (strcmpi (varargin, "FaceColor"))) + nfc = numel (varargin) + 1; + varargin(nfc+(0:1)) = {"FaceColor", "flat"}; + else + nfc = find (any (strcmpi (varargin, "FaceColor")), 1); + endif + if (! any (strcmpi (varargin, "EdgeColor")) + && strcmpi (varargin{nfc+1}, "interp")) + varargin(end+(1:2)) = {"EdgeColor", "none"}; + endif + newplot (); + h = patch ("Faces", tri, "Vertices", [x(:), y(:), z(:)], + "FaceVertexCData", reshape (c, numel (c), 1), + varargin{:}); + if (nargout > 0) + varargout = {h}; + endif + + if (! ishold ()) + set (gca(), "view", [-37.5, 30], + "xgrid", "on", "ygrid", "on", "zgrid", "on"); + endif + endif +endfunction + +%!demo +%! N = 10; +%! rand ('state', 10) +%! x = 3 - 6 * rand (N, N); +%! y = 3 - 6 * rand (N, N); +%! z = peaks (x, y); +%! tri = delaunay (x(:), y(:)); +%! trisurf (tri, x(:), y(:), z(:)); + +%!demo +%! x = rand (100, 1); +%! y = rand (100, 1); +%! z = x.^2 + y.^2; +%! tri = delaunay (x, y); +%! trisurf (tri, x, y, z) + +%!demo +%! x = rand (100, 1); +%! y = rand (100, 1); +%! z = x.^2 + y.^2; +%! tri = delaunay (x, y); +%! trisurf (tri, x, y, z, "facecolor", "interp") + +%!demo +%! x = rand (100, 1); +%! y = rand (100, 1); +%! z = x.^2 + y.^2; +%! tri = delaunay (x, y); +%! trisurf (tri, x, y, z, "facecolor", "interp", "edgecolor", "k") + +
--- a/scripts/plot/whitebg.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/plot/whitebg.m Fri Aug 12 14:16:34 2011 -0400 @@ -74,7 +74,7 @@ if (isroot) fac = get (0, "factory"); fields = fieldnames (fac); - fieldindex = intersect (find (!cellfun (@isempty, regexp(fields, 'color'))), union (find (!cellfun (@isempty, regexp(fields, 'factoryaxes.*'))), find (!cellfun (@isempty, regexp(fields, 'factoryfigure.*'))))); + fieldindex = intersect (find (!cellfun ("isempty", regexp(fields, 'color'))), union (find (!cellfun ("isempty", regexp(fields, 'factoryaxes.*'))), find (!cellfun ("isempty", regexp(fields, 'factoryfigure.*'))))); ## Check whether the factory value has been replaced for nf = 1 : numel (fieldindex); @@ -104,7 +104,7 @@ for nh = 1 : numel(h) p = get (h (nh)); fields = fieldnames (p); - fieldindex = find (!cellfun (@isempty, regexp(fields, 'color'))); + fieldindex = find (!cellfun ("isempty", regexp(fields, 'color'))); if (numel (fieldindex)) for nf = 1 : numel (fieldindex); field = fields {fieldindex (nf)}; @@ -121,7 +121,7 @@ def = get (h (nh), "default"); fields = fieldnames (def); if (! isempty (fields)) - fieldindex = find (!cellfun (@isempty, regexp(fields, 'color'))); + fieldindex = find (!cellfun ("isempty", regexp(fields, 'color'))); for nf = 1 : numel (fieldindex) defaultfield = fields {fieldindex (nf)}; defaultvalue = 1 - subsref (def, struct ("type", ".", "subs", defaultfield));
--- a/scripts/polynomial/mkpp.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/mkpp.m Fri Aug 12 14:16:34 2011 -0400 @@ -17,50 +17,66 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {@var{pp} =} mkpp (@var{x}, @var{p}) -## @deftypefnx {Function File} {@var{pp} =} mkpp (@var{x}, @var{p}, @var{d}) +## @deftypefn {Function File} {@var{pp} =} mkpp (@var{breaks}, @var{coefs}) +## @deftypefnx {Function File} {@var{pp} =} mkpp (@var{breaks}, @var{coefs}, @var{d}) +## +## Construct a piece-wise polynomial (pp) structure from sample points +## @var{breaks} and coefficients @var{coefs}. @var{breaks} must be a vector of +## strictly increasing values. The number of intervals is given by +## @code{@var{ni} = length (@var{breaks}) - 1}. +## When @var{m} is the polynomial order @var{coefs} must be of +## size: @var{ni} x @var{m} + 1. ## -## Construct a piecewise polynomial structure from sample points -## @var{x} and coefficients @var{p}. The i-th row of @var{p}, -## @code{@var{p} (@var{i},:)}, contains the coefficients for the polynomial -## over the @var{i}-th interval, ordered from highest to -## lowest. There must be one row for each interval in @var{x}, so -## @code{rows (@var{p}) == length (@var{x}) - 1}. +## The i-th row of @var{coefs}, +## @code{@var{coefs} (@var{i},:)}, contains the coefficients for the polynomial +## over the @var{i}-th interval, ordered from highest (@var{m}) to +## lowest (@var{0}). ## -## @var{p} may also be a multi-dimensional array, specifying a vector-valued -## or array-valued polynomial. The shape is determined by @var{d}. If @var{d} -## is -## not given, the default is @code{size (p)(1:end-2)}. If @var{d} is given, the -## leading dimensions of @var{p} are reshaped to conform to @var{d}. +## @var{coefs} may also be a multi-dimensional array, specifying a vector-valued +## or array-valued polynomial. In that case the polynomial order is defined +## by the length of the last dimension of @var{coefs}. +## The size of first dimension(s) are given by the scalar or +## vector @var{d}. If @var{d} is not given it is set to @code{1}. +## In any case @var{coefs} is reshaped to a 2d matrix of +## size @code{[@var{ni}*prod(@var{d} @var{m})] } ## ## @seealso{unmkpp, ppval, spline} ## @end deftypefn function pp = mkpp (x, P, d) + + # check number of arguments if (nargin < 2 || nargin > 3) print_usage (); endif - pp.x = x(:); - n = length (x) - 1; - if (n < 1) + + # check x + if (length (x) < 2) error ("mkpp: at least one interval is needed"); endif - nd = ndims (P); - k = size (P, nd); - if (nargin < 3) - if (nd == 2) - d = 1; - else - d = prod (size (P)(1:nd-1)); - endif + + if (!isvector (x)) + error ("mkpp: x must be a vector"); endif - pp.d = d; - pp.P = P = reshape (P, prod (d), [], k); - pp.orient = 0; + + len = length (x) - 1; + dP = length (size (P)); - if (size (P, 2) != n) - error ("mkpp: num intervals in X doesn't match num polynomials in P"); - endif + pp = struct ("form", "pp", + "breaks", x(:).', + "coefs", [], + "pieces", len, + "order", prod (size (P)) / len, + "dim", 1); + + if (nargin == 3) + pp.dim = d; + pp.order /= prod (d); + endif + + dim_vec = [pp.pieces * prod(pp.dim), pp.order]; + pp.coefs = reshape (P, dim_vec); + endfunction %!demo # linear interpolation @@ -72,3 +88,25 @@ %! xi=linspace(0,pi,50); %! plot(x,t,"x",xi,ppval(pp,xi)); %! legend("control","interp"); + +%!shared b,c,pp +%! b = 1:3; c = 1:24; pp=mkpp(b,c); +%!assert (pp.pieces,2); +%!assert (pp.order,12); +%!assert (pp.dim,1); +%!assert (size(pp.coefs),[2,12]); +%! pp=mkpp(b,c,2); +%!assert (pp.pieces,2); +%!assert (pp.order,6); +%!assert (pp.dim,2); +%!assert (size(pp.coefs),[4,6]); +%! pp=mkpp(b,c,3); +%!assert (pp.pieces,2); +%!assert (pp.order,4); +%!assert (pp.dim,3); +%!assert (size(pp.coefs),[6,4]); +%! pp=mkpp(b,c,[2,3]); +%!assert (pp.pieces,2); +%!assert (pp.order,2); +%!assert (pp.dim,[2,3]); +%!assert (size(pp.coefs),[12,2]);
--- a/scripts/polynomial/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -10,7 +10,6 @@ polynomial/poly.m \ polynomial/polyaffine.m \ polynomial/polyder.m \ - polynomial/polyderiv.m \ polynomial/polyfit.m \ polynomial/polygcd.m \ polynomial/polyint.m \
--- a/scripts/polynomial/pchip.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/pchip.m Fri Aug 12 14:16:34 2011 -0400 @@ -27,8 +27,8 @@ ## ## The variable @var{x} must be a strictly monotonic vector (either ## increasing or decreasing). While @var{y} can be either a vector or -## array. In the case where @var{y} is a vector, it must have a length -## of @var{n}. If @var{y} is an array, then the size of @var{y} must +## an array. In the case where @var{y} is a vector, it must have the +## length @var{n}. If @var{y} is an array, then the size of @var{y} must ## have the form ## @tex ## $$[s_1, s_2, \cdots, s_k, n]$$ @@ -73,15 +73,22 @@ print_usage (); endif + ## make row vector x = x(:).'; n = length (x); ## Check the size and shape of y if (isvector (y)) - y = y(:).'; + y = y(:).'; ##row vector szy = size (y); + if !(size_equal (x, y)) + error ("pchip: length of X and Y must match") + endif else szy = size (y); + if (n != szy(end)) + error ("pchip: length of X and last dimension of Y must match") + endif y = reshape (y, [prod(szy(1:end-1)), szy(end)]); endif @@ -94,16 +101,12 @@ error("pchip: X must be strictly monotonic"); endif - if (columns (y) != n) - error("pchip: size of X and Y must match"); - endif - - f1 = y(:,1:n-1); + f1 = y(:, 1:n-1); ## Compute derivatives. d = __pchip_deriv__ (x, y, 2); - d1 = d(:,1:n-1); - d2 = d(:,2:n); + d1 = d(:, 1:n-1); + d2 = d(:, 2:n); ## This is taken from SLATEC. h = diag (h); @@ -114,14 +117,12 @@ c3 = del1 + del2; c2 = -c3 - del1; c3 = c3 / h; - coeffs = cat (3, c3, c2, d1, f1); - pp = mkpp (x, coeffs, szy(1:end-1)); - if (nargin == 2) - ret = pp; - else - ret = ppval (pp, xi); + ret = mkpp (x, coeffs, szy(1:end-1)); + + if (nargin == 3) + ret = ppval (ret, xi); endif endfunction @@ -138,7 +139,7 @@ %! %------------------------------------------------------------------- %! % confirm that pchip agreed better to discontinuous data than spline -%!shared x,y +%!shared x,y,y2,pp,yi1,yi2,yi3 %! x = 0:8; %! y = [1, 1, 1, 1, 0.5, 0, 0, 0, 0]; %!assert (pchip(x,y,x), y); @@ -148,3 +149,23 @@ %!assert (isempty(pchip(x',y',[]))); %!assert (isempty(pchip(x,y,[]))); %!assert (pchip(x,[y;y],x), [pchip(x,y,x);pchip(x,y,x)]) +%!assert (pchip(x,[y;y],x'), [pchip(x,y,x);pchip(x,y,x)]) +%!assert (pchip(x',[y;y],x), [pchip(x,y,x);pchip(x,y,x)]) +%!assert (pchip(x',[y;y],x'), [pchip(x,y,x);pchip(x,y,x)]) +%!test +%! x=(0:8)*pi/4;y=[sin(x);cos(x)]; +%! y2(:,:,1)=y;y2(:,:,2)=y+1;y2(:,:,3)=y-1; +%! pp=pchip(x,shiftdim(y2,2)); +%! yi1=ppval(pp,(1:4)*pi/4); +%! yi2=ppval(pp,repmat((1:4)*pi/4,[5,1])); +%! yi3=ppval(pp,[pi/2,pi]); +%!assert(size(pp.coefs),[48,4]); +%!assert(pp.pieces,8); +%!assert(pp.order,4); +%!assert(pp.dim,[3,2]); +%!assert(ppval(pp,pi),[0,-1;1,0;-1,-2],1e-14); +%!assert(yi3(:,:,2),ppval(pp,pi),1e-14); +%!assert(yi3(:,:,1),[1,0;2,1;0,-1],1e-14); +%!assert(squeeze(yi1(1,2,:)),[1/sqrt(2); 0; -1/sqrt(2);-1],1e-14); +%!assert(size(yi2),[3,2,5,4]); +%!assert(squeeze(yi2(1,2,3,:)),[1/sqrt(2); 0; -1/sqrt(2);-1],1e-14); \ No newline at end of file
--- a/scripts/polynomial/polyder.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/polyder.m Fri Aug 12 14:16:34 2011 -0400 @@ -1,4 +1,4 @@ -## Copyright (C) 1995-2011 John W. Eaton +## Copyright (C) 1994-2011 John W. Eaton ## ## This file is part of Octave. ## @@ -17,27 +17,84 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} polyderiv (@var{p}) -## @deftypefnx {Function File} {[@var{k}] =} polyderiv (@var{a}, @var{b}) -## @deftypefnx {Function File} {[@var{q}, @var{d}] =} polyderiv (@var{b}, @var{a}) -## An alias for @code{polyderiv}. -## @seealso{polyderiv} +## @deftypefn {Function File} {} polyder (@var{p}) +## @deftypefnx {Function File} {[@var{k}] =} polyder (@var{a}, @var{b}) +## @deftypefnx {Function File} {[@var{q}, @var{d}] =} polyder (@var{b}, @var{a}) +## Return the coefficients of the derivative of the polynomial whose +## coefficients are given by the vector @var{p}. If a pair of polynomials +## is given, return the derivative of the product @math{@var{a}*@var{b}}. +## If two inputs and two outputs are given, return the derivative of the +## polynomial quotient @math{@var{b}/@var{a}}. The quotient numerator is +## in @var{q} and the denominator in @var{d}. +## @seealso{poly, polyint, polyreduce, roots, conv, deconv, residue, +## filter, polygcd, polyval, polyvalm} ## @end deftypefn -## Author: John W. Eaton +## Author: Tony Richardson <arichard@stark.cc.oh.us> +## Created: June 1994 +## Adapted-By: jwe function [q, d] = polyder (p, a) - if (nargin == 1) - q = polyderiv (p); - elseif (nargin == 2) - if (nargout == 2) - [q, d] = polyderiv (p, a); + if (nargin == 1 || nargin == 2) + if (! isvector (p)) + error ("polyder: argument must be a vector"); + endif + if (nargin == 2) + if (! isvector (a)) + error ("polyder: argument must be a vector"); + endif + if (nargout == 1) + ## derivative of p*a returns a single polynomial + q = polyder (conv (p, a)); + else + ## derivative of p/a returns numerator and denominator + d = conv (a, a); + if (numel (p) == 1) + q = -p * polyder (a); + elseif (numel (a) == 1) + q = a * polyder (p); + else + q = conv (polyder (p), a) - conv (p, polyder (a)); + q = polyreduce (q); + endif + + ## remove common factors from numerator and denominator + x = polygcd (q, d); + if (length(x) != 1) + q = deconv (q, x); + d = deconv (d, x); + endif + + ## move all the gain into the numerator + q = q/d(1); + d = d/d(1); + endif else - q = polyderiv (p, a); + lp = numel (p); + if (lp == 1) + q = 0; + return; + elseif (lp == 0) + q = []; + return; + endif + + ## Force P to be a row vector. + p = p(:).'; + + q = p(1:(lp-1)) .* [(lp-1):-1:1]; endif else print_usage (); endif endfunction + + +%!assert(all (all (polyder ([1, 2, 3]) == [2, 2]))); +%!assert(polyder (13) == 0); + +%!error polyder ([]); +%!error polyder ([1, 2; 3, 4]); +
--- a/scripts/polynomial/polyderiv.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,101 +0,0 @@ -## Copyright (C) 1994-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} polyderiv (@var{p}) -## @deftypefnx {Function File} {[@var{k}] =} polyderiv (@var{a}, @var{b}) -## @deftypefnx {Function File} {[@var{q}, @var{d}] =} polyderiv (@var{b}, @var{a}) -## Return the coefficients of the derivative of the polynomial whose -## coefficients are given by the vector @var{p}. If a pair of polynomials -## is given, return the derivative of the product @math{@var{a}*@var{b}}. -## If two inputs and two outputs are given, return the derivative of the -## polynomial quotient @math{@var{b}/@var{a}}. The quotient numerator is -## in @var{q} and the denominator in @var{d}. -## @seealso{poly, polyint, polyreduce, roots, conv, deconv, residue, -## filter, polygcd, polyval, polyvalm} -## @end deftypefn - -## Author: Tony Richardson <arichard@stark.cc.oh.us> -## Created: June 1994 -## Adapted-By: jwe - -function [q, d] = polyderiv (p, a) - - if (nargin == 1 || nargin == 2) - if (! isvector (p)) - error ("polyderiv: argument must be a vector"); - endif - if (nargin == 2) - if (! isvector (a)) - error ("polyderiv: argument must be a vector"); - endif - if (nargout == 1) - ## derivative of p*a returns a single polynomial - q = polyderiv (conv (p, a)); - else - ## derivative of p/a returns numerator and denominator - d = conv (a, a); - if (numel (p) == 1) - q = -p * polyderiv (a); - elseif (numel (a) == 1) - q = a * polyderiv (p); - else - q = conv (polyderiv (p), a) - conv (p, polyderiv (a)); - q = polyreduce (q); - endif - - ## remove common factors from numerator and denominator - x = polygcd (q, d); - if (length(x) != 1) - q = deconv (q, x); - d = deconv (d, x); - endif - - ## move all the gain into the numerator - q = q/d(1); - d = d/d(1); - endif - else - lp = numel (p); - if (lp == 1) - q = 0; - return; - elseif (lp == 0) - q = []; - return; - endif - - ## Force P to be a row vector. - p = p(:).'; - - q = p(1:(lp-1)) .* [(lp-1):-1:1]; - endif - else - print_usage (); - endif - -endfunction - -%!assert(all (all (polyderiv ([1, 2, 3]) == [2, 2]))); - -%!assert(polyderiv (13) == 0); - -%!error polyderiv ([]); - -%!error polyderiv ([1, 2; 3, 4]); -
--- a/scripts/polynomial/polyint.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/polyint.m Fri Aug 12 14:16:34 2011 -0400 @@ -61,3 +61,18 @@ retval = [(p ./ [lp:-1:1]), k]; endfunction + +%!test +%! A = [3, 2, 1]; +%! assert (polyint(A),polyint(A,0)); +%! assert (polyint(A),polyint(A')); +%! assert (polyint(A),[1, 1, 1, 0]); +%! assert (polyint(A,1),ones(1,4)); + +%!test +%! A = ones(1,8); +%! B = [length(A):-1:1]; +%! assert (polyint(A),[1./B, 0]); + +%!error polyint() +%!error polyint(ones(2,2))
--- a/scripts/polynomial/polyout.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/polyout.m Fri Aug 12 14:16:34 2011 -0400 @@ -97,3 +97,9 @@ str = num2str (c, 5); endif endfunction + +%!assert (polyout ([3 2 1]), '3*s^2 + 2*s^1 + 1') +%!assert (polyout ([3 2 1], 'x'), '3*x^2 + 2*x^1 + 1') +%!assert (polyout ([3 2 1], 'wxyz'), '3*wxyz^2 + 2*wxyz^1 + 1') +%!assert (polyout ([5 4 3 2 1], '1'),'5*1^4 + 4*1^3 + 3*1^2 + 2*1^1 + 1') +%!error polyout ([])
--- a/scripts/polynomial/ppder.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/ppder.m Fri Aug 12 14:16:34 2011 -0400 @@ -17,28 +17,54 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {@var{ppd} =} ppder (@var{pp}) -## Compute the piecewise derivative of the piecewise polynomial struct @var{pp}. +## @deftypefn {Function File} {ppd =} ppder (pp, m) +## Computes the piecewise @var{m}-th derivative of a piecewise polynomial +## struct @var{pp}. If @var{m} is omitted the first derivate is +## calculated. ## @seealso{mkpp, ppval, ppint} ## @end deftypefn -function ppd = ppder (pp) - if (nargin != 1) +function ppd = ppder (pp, m) + + if ((nargin < 1) || (nargin > 2)) print_usage (); + elseif (nargin == 1) + m = 1; endif - if (! isstruct (pp)) + + if !(isstruct (pp) && strcmp (pp.form, "pp")) error ("ppder: PP must be a structure"); endif [x, p, n, k, d] = unmkpp (pp); - p = reshape (p, [], k); - if (k <= 1) - pd = zeros (rows (p), 1); - k = 1; + + if (k - m <= 0) + x = [x(1) x(end)]; + pd = zeros (prod (d), 1); else - k -= 1; - pd = p(:,1:k) * diag (k:-1:1); + f = k : -1 : 1; + ff = bincoeff (f, m + 1) .* factorial (m + 1) ./ f; + k -= m; + pd = p(:,1:k) * diag (ff(1:k)); endif + ppd = mkpp (x, pd, d); endfunction +%!shared x,y,pp,ppd +%! x=0:8;y=[x.^2;x.^3+1];pp=spline(x,y); +%! ppd=ppder(pp); +%!assert(ppval(ppd,x),[2*x;3*x.^2],1e-14) +%!assert(ppd.order,3) +%! ppd=ppder(pp,2); +%!assert(ppval(ppd,x),[2*ones(size(x));6*x],1e-14) +%!assert(ppd.order,2) +%! ppd=ppder(pp,3); +%!assert(ppd.order,1) +%!assert(ppd.pieces,8) +%!assert(size(ppd.coefs),[16,1]) +%! ppd=ppder(pp,4); +%!assert(ppd.order,1) +%!assert(ppd.pieces,1) +%!assert(size(ppd.coefs),[2,1]) +%!assert(ppval(ppd,x),zeros(size(y)),1e-14)
--- a/scripts/polynomial/ppint.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/ppint.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,7 +28,7 @@ if (nargin < 1 || nargin > 2) print_usage (); endif - if (! isstruct (pp)) + if (! isstruct (pp) && strcmp (pp.form, "pp")) error ("ppint: PP must be a structure"); endif @@ -39,17 +39,20 @@ pi = p / diag (k:-1:1); k += 1; if (nargin == 1) - pi(:,k) = 0; + pi(:, k) = 0; else - pi(:,k) = repmat (c(:), n, 1); + pi(:, k) = repmat (c(:), n, 1); endif ppi = mkpp (x, pi, d); - ## Adjust constants so the the result is continuous. - - jumps = reshape (ppjumps (ppi), prod (d), n-1); - ppi.P(:,2:n,k) -= cumsum (jumps, 2); - + tmp = -cumsum (ppjumps (ppi), length (d) + 1); + ppi.coefs(prod(d)+1:end, k) = tmp(:); + endfunction +%!shared x,y,pp,ppi +%! x=0:8;y=[ones(size(x));x+1];pp=spline(x,y); +%! ppi=ppint(pp); +%!assert(ppval(ppi,x),[x;0.5*x.^2+x],1e-14) +%!assert(ppi.order,5)
--- a/scripts/polynomial/ppjumps.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/ppjumps.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,29 +28,31 @@ if (nargin != 1) print_usage (); endif - if (! isstruct (pp)) + + if (! isstruct (pp) && strcmp (pp.form, "pp")) error ("ppjumps: PP must be a structure"); endif ## Extract info. - x = pp.x; - P = pp.P; - d = pp.d; - [nd, n, k] = size (P); + [x, P, n, k, d] = unmkpp(pp); + nd = length (d) + 1; ## Offsets. - dx = diff (x(1:n)).'; - dx = dx(ones (1, nd), :); # spread (do nothing in 1D) + dx = diff(x(1:n)); + dx = repmat (dx, [prod(d), 1]); + dx = reshape (dx, [d, n-1]); + dx = shiftdim (dx, nd - 1); - ## Use Horner scheme to get limits from the left. - llim = P(:,1:n-1,1); - for i = 2:k; + ## Use Horner scheme. + if (k>1) + llim = shiftdim (reshape (P(1:(n-1) * prod(d), 1), [d, n-1]), nd - 1); + endif + + for i = 2 : k; llim .*= dx; - llim += P(:,1:n-1,i); + llim += shiftdim (reshape (P(1:(n-1) * prod (d), i), [d, n-1]), nd - 1); endfor - - rlim = P(:,2:n,k); # limits from the right - jumps = reshape (rlim - llim, [d, n-1]); - + + rlim = shiftdim (ppval (pp, x(2:end-1)), nd - 1); + jumps = shiftdim (rlim - llim, 1); endfunction -
--- a/scripts/polynomial/ppval.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/ppval.m Fri Aug 12 14:16:34 2011 -0400 @@ -18,16 +18,18 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {@var{yi} =} ppval (@var{pp}, @var{xi}) -## Evaluate piecewise polynomial @var{pp} at the points @var{xi}. -## If @var{pp} is scalar-valued, the result is an array of the same shape as -## @var{xi}. -## Otherwise, the size of the result is @code{[pp.d, length(@var{xi})]} if -## @var{xi} is a vector, or @code{[pp.d, size(@var{xi})]} if it is a -## multi-dimensional array. If pp.orient is 1, the dimensions are permuted as +## Evaluate piece-wise polynomial structure @var{pp} at the points @var{xi}. +## If @var{pp} describes a scalar polynomial function, the result is an +## array of the same shape as @var{xi}. +## Otherwise, the size of the result is @code{[pp.dim, length(@var{xi})]} if +## @var{xi} is a vector, or @code{[pp.dim, size(@var{xi})]} if it is a +## multi-dimensional array. +## +##, the dimensions are permuted as ## in interp1, to ## @code{[pp.d, length(@var{xi})]} and @code{[pp.d, size(@var{xi})]} ## respectively. -## @seealso{mkpp, unmkpp, spline} +## @seealso{mkpp, unmkpp, spline, pchip, interp1} ## @end deftypefn function yi = ppval (pp, xi) @@ -35,48 +37,85 @@ if (nargin != 2) print_usage (); endif - if (! isstruct (pp)) - error ("ppval: PP must be a structure"); + if (! isstruct (pp) && strcmp (pp.form, "pp")) + error ("ppval: expects a pp-form structure"); endif ## Extract info. - x = pp.x; - P = pp.P; - d = pp.d; - k = size (P, 3); - nd = size (P, 1); - - ## Determine resulting shape. - if (d == 1) # scalar case - yisz = size (xi); - elseif (isvector (xi)) # this is special - yisz = [d, length(xi)]; - else # general - yisz = [d, size(xi)]; + [x, P, n, k, d] = unmkpp (pp); + + ## dimension checks + sxi = size (xi); + if (isvector (xi)) + xi = xi(:).'; endif + + nd = length (d); ## Determine intervals. - xi = xi(:); xn = numel (xi); - idx = lookup (x, xi, "lr"); + P = reshape (P, [d, n * k]); + P = shiftdim (P, nd); + P = reshape (P, [n, k, d]); + Pidx = P(idx(:), :);#2d matrix size x: coefs*prod(d) y: prod(sxi) + + if (isvector(xi)) + Pidx = reshape (Pidx, [xn, k, d]); + Pidx = shiftdim (Pidx, 1); + dimvec = [d, xn]; + else + Pidx = reshape (Pidx, [sxi, k, d]); + Pidx = shiftdim (Pidx, length (sxi)); + dimvec = [d, sxi]; + end + ndv = length (dimvec); + ## Offsets. - dx = (xi - x(idx)).'; - dx = dx(ones (1, nd), :); # spread (do nothing in 1D) + dx = (xi - x(idx)); + dx = repmat (dx, [prod(d), 1]); + dx = reshape (dx, dimvec); + dx = shiftdim (dx, ndv - 1); ## Use Horner scheme. - yi = P(:,idx,1); - for i = 2:k; + yi = Pidx; + if (k > 1) + yi = shiftdim (reshape (Pidx(1,:), dimvec), ndv - 1); + endif + + for i = 2 : k; yi .*= dx; - yi += P(:,idx,i); + yi += shiftdim (reshape (Pidx(i,:), dimvec), ndv - 1); endfor - + ## Adjust shape. - yi = reshape (yi, yisz); - if (d != 1 && pp.orient == 1) - ## Switch dimensions to match interp1 order. - yi = shiftdim (yi, length (d)); + if ((numel (xi) > 1) || (length (d) == 1)) + yi = reshape (shiftdim (yi, 1), dimvec); endif + if (isvector (xi) && (d == 1)) + yi = reshape (yi, sxi); + elseif (isfield (pp, "orient") && strcmp (pp.orient, "first")) + yi = shiftdim(yi, nd); + endif + + ## + #if (d == 1) + # yi = reshape (yi, sxi); + #endif + endfunction + +%!shared b,c,pp,pp2,xi,abserr +%! b = 1:3; c = ones(2); pp=mkpp(b,c);abserr = 1e-14;pp2=mkpp(b,[c;c],2); +%! xi = [1.1 1.3 1.9 2.1]; +%!assert (ppval(pp,1.1), 1.1, abserr); +%!assert (ppval(pp,2.1), 1.1, abserr); +%!assert (ppval(pp,xi), [1.1 1.3 1.9 1.1], abserr); +%!assert (ppval(pp,xi.'), [1.1 1.3 1.9 1.1].', abserr); +%!assert (ppval(pp2,1.1), [1.1;1.1], abserr); +%!assert (ppval(pp2,2.1), [1.1;1.1], abserr); +%!assert (ppval(pp2,xi), [1.1 1.3 1.9 1.1;1.1 1.3 1.9 1.1], abserr); +%!assert (ppval(pp2,xi'), [1.1 1.3 1.9 1.1;1.1 1.3 1.9 1.1], abserr); +%!assert (size(ppval(pp2,[xi;xi])), [2 2 4]);
--- a/scripts/polynomial/spline.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/spline.m Fri Aug 12 14:16:34 2011 -0400 @@ -83,15 +83,15 @@ ## Check the size and shape of y ndy = ndims (y); szy = size (y); - if (ndy == 2 && (szy(1) == 1 || szy(2) == 1)) - if (szy(1) == 1) + if (ndy == 2 && (szy(1) == n || szy(2) == n)) + if (szy(2) == n) a = y.'; else a = y; szy = fliplr (szy); endif else - a = reshape (y, [prod(szy(1:end-1)), szy(end)]).'; + a = shiftdim (reshape (y, [prod(szy(1:end-1)), szy(end)]), 1); endif for k = (1:columns (a))(any (isnan (a))) @@ -120,9 +120,9 @@ if (n == 2) d = (dfs + dfe) / (x(2) - x(1)) ^ 2 + ... - 2 * (a(1,:) - a(2,:)) / (x(2) - x(1)) ^ 3; + 2 * (a(1,:) - a(2,:)) / (x(2) - x(1)) ^ 3; c = (-2 * dfs - dfe) / (x(2) - x(1)) - ... - 3 * (a(1,:) - a(2,:)) / (x(2) - x(1)) ^ 2; + 3 * (a(1,:) - a(2,:)) / (x(2) - x(1)) ^ 2; b = dfs; a = a(1,:); @@ -132,7 +132,7 @@ a = a(1:n-1,:); else if (n == 3) - dg = 1.5 * h(1) - 0.5 * h(2); + dg = 1.5 * h(1) - 0.5 * h(2); c(2:n-1,:) = 1/dg(1); else dg = 2 * (h(1:n-2) .+ h(2:n-1)); @@ -153,9 +153,9 @@ endif c(1,:) = (3 / h(1) * (a(2,:) - a(1,:)) - 3 * dfs - - c(2,:) * h(1)) / (2 * h(1)); + - c(2,:) * h(1)) / (2 * h(1)); c(n,:) = - (3 / h(n-1) * (a(n,:) - a(n-1,:)) - 3 * dfe - + c(n-1,:) * h(n-1)) / (2 * h(n-1)); + + c(n-1,:) * h(n-1)) / (2 * h(n-1)); b(1:n-1,:) = diff (a) ./ h(1:n-1, idx) ... - h(1:n-1,idx) / 3 .* (c(2:n,:) + 2 * c(1:n-1,:)); d = diff (c) ./ (3 * h(1:n-1, idx)); @@ -229,15 +229,14 @@ - h(1:n-1, idx) / 3 .* (c(2:n,:) + 2 * c(1:n-1,:)); d = diff (c) ./ (3 * h(1:n-1, idx)); - d = d(1:n-1,:); - c = c(1:n-1,:); - b = b(1:n-1,:); - a = a(1:n-1,:); + d = d(1:n-1,:);d = d.'(:); + c = c(1:n-1,:);c = c.'(:); + b = b(1:n-1,:);b = b.'(:); + a = a(1:n-1,:);a = a.'(:); endif endif - coeffs = cat (3, d.', c.', b.', a.'); - ret = mkpp (x, coeffs, szy(1:end-1)); + ret = mkpp (x, cat (2, d, c, b, a), szy(1:end-1)); if (nargin == 3) ret = ppval (ret, xi); @@ -263,6 +262,9 @@ %!assert (isempty(spline(x',y',[]))); %!assert (isempty(spline(x,y,[]))); %!assert (spline(x,[y;y],x), [spline(x,y,x);spline(x,y,x)],abserr) +%!assert (spline(x,[y;y],x'), [spline(x,y,x);spline(x,y,x)],abserr) +%!assert (spline(x',[y;y],x), [spline(x,y,x);spline(x,y,x)],abserr) +%!assert (spline(x',[y;y],x'), [spline(x,y,x);spline(x,y,x)],abserr) %! y = cos(x) + i*sin(x); %!assert (spline(x,y,x), y, abserr) %!assert (real(spline(x,y,x)), real(y), abserr);
--- a/scripts/polynomial/unmkpp.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/polynomial/unmkpp.m Fri Aug 12 14:16:34 2011 -0400 @@ -50,15 +50,13 @@ if (nargin == 0) print_usage (); endif - if (! isstruct (pp)) + if (! (isstruct (pp) && strcmp (pp.form, "pp"))) error ("unmkpp: expecting piecewise polynomial structure"); endif - x = pp.x; - P = pp.P; - n = size (P, 2); - k = size (P, 3); - d = pp.d; - if (d == 1) - P = reshape (P, n, k); - endif + x = pp.breaks; + P = pp.coefs; + n = pp.pieces; + k = pp.order; + d = pp.dim; + endfunction
--- a/scripts/set/powerset.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/set/powerset.m Fri Aug 12 14:16:34 2011 -0400 @@ -75,3 +75,9 @@ endif endfunction + + +%!test +%! c = sort (cellstr ({ [], [1], [2], [3], [1, 2], [1, 3], [2, 3], [1, 2, 3]})); +%! p = sort (cellstr (powerset ([1, 2, 3]))); +%! assert (p, c);
--- a/scripts/set/setxor.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/set/setxor.m Fri Aug 12 14:16:34 2011 -0400 @@ -1,17 +1,17 @@ -## Copyright (C) 2008-2011 Jaroslav Hajek +## Copyright (C) 2008-2011 Jaroslav Hajek ## Copyright (C) 2000, 2006-2007 Paul Kienzle ## ## This file is part of Octave. ## ## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at +## under the terms of the GNU General Public License as published by the +## Free Software Foundation; either version 3 of the License, or (at ## your option) any later version. ## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. +## Octave is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +## for more details. ## ## You should have received a copy of the GNU General Public License ## along with Octave; see the file COPYING. If not, see @@ -20,17 +20,16 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} setxor (@var{a}, @var{b}) ## @deftypefnx {Function File} {} setxor (@var{a}, @var{b}, 'rows') +## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@var{a}, @var{b}) ## ## Return the elements exclusive to @var{a} or @var{b}, sorted in ascending ## order. If @var{a} and @var{b} are both column vectors return a column ## vector, otherwise return a row vector. ## @var{a}, @var{b} may be cell arrays of string(s). ## -## @deftypefnx {Function File} {[@var{c}, @var{ia}, @var{ib}] =} setxor (@var{a}, @var{b}) -## -## Return index vectors @var{ia} and @var{ib} such that @code{a(ia)} and -## @code{b(ib)} are -## disjoint sets whose union is @var{c}. +## With three output arguments, return index vectors @var{ia} and @var{ib} +## such that @code{a(ia)} and @code{b(ib)} are disjoint sets whose union +## is @var{c}. ## ## @seealso{unique, union, intersect, setdiff, ismember} ## @end deftypefn
--- a/scripts/signal/autoreg_matrix.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/signal/autoreg_matrix.m Fri Aug 12 14:16:34 2011 -0400 @@ -47,3 +47,16 @@ endfor endfunction + + +%!test +%! K=4; +%! A = zeros(1,K+1); +%! A(1) = 1; +%! B = eye(K+1); +%! B(:,1) = 1; +%! assert (autoreg_matrix(A,K),B); + +%!error autoreg_matrix() +%!error autoreg_matrix(1) +%!error autoreg_matrix(ones(4,1),5)
--- a/scripts/signal/fftshift.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/signal/fftshift.m Fri Aug 12 14:16:34 2011 -0400 @@ -58,9 +58,7 @@ sz = size (x); sz2 = ceil (sz(dim) / 2); idx = cell (); - for i = 1:nd - idx{i} = 1:sz(i); - endfor + idx = repmat ({':'}, nd, 1); idx{dim} = [sz2+1:sz(dim), 1:sz2]; retval = x(idx{:}); else
--- a/scripts/signal/ifftshift.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/signal/ifftshift.m Fri Aug 12 14:16:34 2011 -0400 @@ -45,10 +45,7 @@ nd = ndims (x); sz = size (x); sz2 = floor (sz(dim) / 2); - idx = cell (); - for i = 1:nd - idx{i} = 1:sz(i); - endfor + idx = repmat ({':'}, nd, 1); idx{dim} = [sz2+1:sz(dim), 1:sz2]; retval = x(idx{:}); else
--- a/scripts/signal/sinc.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/signal/sinc.m Fri Aug 12 14:16:34 2011 -0400 @@ -45,3 +45,10 @@ endif endfunction + + +%!assert (sinc (0), 1); +%!assert (sinc (1), 0,1e-6); +%!assert (sinc (1/2), 2/pi, 1e-6) + +%!error sinc()
--- a/scripts/signal/sinewave.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/signal/sinewave.m Fri Aug 12 14:16:34 2011 -0400 @@ -43,3 +43,13 @@ endif endfunction + +%!assert (sinewave (1), 0); +%!assert (sinewave (1, 4, 1), 1); +%!assert (sinewave (1, 12, 1), 1/2, 1e-6); +%!assert (sinewave (1, 12, 2), sqrt (3)/2, 1e-6); +%!assert (sinewave (1, 20, 1), (sqrt (5)-1)/4, 1e-6); +%!assert (sinewave (1), sinewave (1, 1,0)); +%!assert (sinewave (3, 4), sinewave(3, 4, 0)); + +%!error sinewave ();
--- a/scripts/signal/unwrap.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/signal/unwrap.m Fri Aug 12 14:16:34 2011 -0400 @@ -55,11 +55,8 @@ error ("unwrap: DIM must be an integer and a valid dimension"); endif else - ## Find the first non-singleton dimension - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + ## Find the first non-singleton dimension. + (dim = find (sz > 1, 1)) || (dim = 1); endif rng = 2*pi; @@ -74,17 +71,14 @@ ## Take first order difference to see so that wraps will show up ## as large values, and the sign will show direction. - idx = cell (); - for i = 1:nd - idx{i} = 1:sz(i); - endfor + idx = repmat ({':'}, nd, 1); idx{dim} = [1,1:m-1]; d = x(idx{:}) - x; - ## Find only the peaks, and multiply them by the range so that there - ## are kronecker deltas at each wrap point multiplied by the range - ## value. - p = rng * (((d > tol) > 0) - ((d < -tol) > 0)); + ## Find only the peaks, and multiply them by the appropriate amount + ## of ranges so that there are kronecker deltas at each wrap point + ## multiplied by the appropriate amount of range values. + p = ceil(abs(d)./rng) .* rng .* (((d > tol) > 0) - ((d < -tol) > 0)); ## Now need to "integrate" this so that the deltas become steps. r = cumsum (p, dim); @@ -134,4 +128,28 @@ %! t(++i) = xassert(any(abs(r - unwrap(w,0.8)) > 100)); %! %! assert(all(t)); - +%! +%!test +%! A = [pi*(-4), pi*(-2+1/6), pi/4, pi*(2+1/3), pi*(4+1/2), pi*(8+2/3), pi*(16+1), pi*(32+3/2), pi*64]; +%! assert (unwrap(A), unwrap(A, pi)); +%! assert (unwrap(A, pi), unwrap(A, pi, 2)); +%! assert (unwrap(A', pi), unwrap(A', pi, 1)); +%! +%!test +%! A = [pi*(-4); pi*(2+1/3); pi*(16+1)]; +%! B = [pi*(-2+1/6); pi*(4+1/2); pi*(32+3/2)]; +%! C = [pi/4; pi*(8+2/3); pi*64]; +%! D = [pi*(-2+1/6); pi*(2+1/3); pi*(8+2/3)]; +%! E(:, :, 1) = [A, B, C, D]; +%! E(:, :, 2) = [A+B, B+C, C+D, D+A]; +%! F(:, :, 1) = [unwrap(A), unwrap(B), unwrap(C), unwrap(D)]; +%! F(:, :, 2) = [unwrap(A+B), unwrap(B+C), unwrap(C+D), unwrap(D+A)]; +%! assert (unwrap(E), F); +%! +%!test +%! A = [0, 2*pi, 4*pi, 8*pi, 16*pi, 65536*pi]; +%! B = [pi*(-2+1/6), pi/4, pi*(2+1/3), pi*(4+1/2), pi*(8+2/3), pi*(16+1), pi*(32+3/2), pi*64]; +%! assert (unwrap(A), zeros(1, length(A))); +%! assert (diff(unwrap(B), 1)<2*pi, true(1, length(B)-1)); +%! +%!error unwrap()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/sparse/gmres.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,214 @@ +## Copyright (C) 2009-2011 Carlo de Falco +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by the +## Free Software Foundation; either version 3 of the License, or (at your +## option) any later version. +## +## Octave is distributed in the hope that it will be useful, but WITHOUT +## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +## for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {@var{x} =} gmres (@var{A}, @var{b}, @var{m}, @var{rtol}, @var{maxit}, @var{M1}, @var{M2}, @var{x0}) +## @deftypefnx {Function File} {@var{x} =} gmres (@var{A}, @var{b}, @var{m}, @var{rtol}, @var{maxit}, @var{P}) +## @deftypefnx {Function File} {[@var{x}, @var{flag}, @var{relres}, @var{iter}, @var{resvec}] =} gmres (@dots{}) +## Solve @code{A x = b} using the Preconditioned GMRES iterative method +## with restart, a.k.a. PGMRES(m). +## +## @itemize @minus +## @item @var{rtol} is the relative tolerance, +## if not given or set to [] the default value 1e-6 is used. +## +## @item @var{maxit} is the maximum number of outer iterations, +## if not given or set to [] the default value +## @code{min (10, numel (b) / restart)} is used. +## +## @item @var{x0} is the initial guess, +## if not given or set to [] the default value @code{zeros(size (b))} is used. +## +## @item @var{m} is the restart parameter, +## if not given or set to [] the default value @code{numel (b)} is used. +## @end itemize +## +## Argument @var{A} can be passed as a matrix, function handle, or +## inline function @code{f} such that @code{f(x) = A*x}. +## +## The preconditioner @var{P} is given as @code{P = M1 * M2}. +## Both @var{M1} and @var{M2} can be passed as a matrix, function handle, or +## inline function @code{g} such that @code{g(x) = M1\x} or @code{g(x) = M2\x}. +## +## Besides the vector @var{x}, additional outputs are: +## +## @itemize @minus +## @item @var{flag} indicates the exit status: +## +## @table @asis +## @item 0 : iteration converged to within the specified tolerance +## +## @item 1 : maximum number of iterations exceeded +## +## @item 2 : unused, but skipped for compatibility +## +## @item 3 : algorithm reached stagnation +## @end table +## +## @item @var{relres} is the final value of the relative residual. +## +## @item @var{iter} is a vector containing the number of outer iterations and +## total iterations performed. +## +## @item @var{resvec} is a vector containing the relative residual at each +## iteration. +## @end itemize +## +## @seealso{pcg, cgs, bicgstab} +## @end deftypefn + +function [x, flag, prec_res_norm, itcnt] = gmres (A, b, restart, rtol, maxit, M1, M2, x0) + + if (nargin < 2 || nargin > 8) + print_usage (); + end + + if (ischar (A)) + Ax = str2func (A); + elseif (ismatrix (A)) + Ax = @(x) A*x; + elseif (isa (A, "function_handle")) + Ax = A; + else + error ("gmres: A must be a function or matrix"); + endif + + if (nargin < 3 || isempty (restart)) + restart = rows (b); + endif + + if (nargin < 4 || isempty (rtol)) + rtol = 1e-6; + endif + + if (nargin < 5 || isempty (maxit)) + maxit = min (rows (b)/restart, 10); + endif + + if (nargin < 6 || isempty (M1)) + M1m1x = @(x) x; + elseif (ischar (M1)) + M1m1x = str2func (M1); + elseif (ismatrix (M1)) + M1m1x = @(x) M1 \ x; + elseif (isa (M1, "function_handle")) + M1m1x = M1; + else + error ("gmres: preconditioner M1 must be a function or matrix"); + endif + + if (nargin < 7 || isempty (M2)) + M2m1x = @(x) x; + elseif (ischar (M2)) + M2m1x = str2func (M2); + elseif (ismatrix (M2)) + M2m1x = @(x) M2 \ x; + elseif (isa (M2, "function_handle")) + M2m1x = M2; + else + error ("gmres: preconditioner M2 must be a function or matrix"); + endif + + Pm1x = @(x) M2m1x (M1m1x (x)); + + if (nargin < 8 || isempty (x0)) + x0 = zeros (size (b)); + endif + + x_old = x0; + x = x_old; + prec_res = Pm1x (b - Ax (x_old)); + prec_res_norm = norm (prec_res, 2); + + B = zeros (restart + 1, 1); + V = zeros (rows (x), restart); + H = zeros (restart + 1, restart); + + ## begin loop + iter = 1; + restart_it = restart + 1; + resids = zeros (maxit, 1); + resids(1) = prec_res_norm; + prec_b_norm = norm (Pm1x (b), 2); + flag = 1; + + while ((iter <= maxit * restart) && (prec_res_norm > rtol * prec_b_norm)) + + ## restart + if (restart_it > restart) + restart_it = 1; + x_old = x; + prec_res = Pm1x (b - Ax (x_old)); + prec_res_norm = norm (prec_res, 2); + B(1) = prec_res_norm; + H(:) = 0; + V(:, 1) = prec_res / prec_res_norm; + endif + + ## basic iteration + tmp = Pm1x (Ax (V(:, restart_it))); + [V(:,restart_it+1), H(1:restart_it+1, restart_it)] = mgorth (tmp, V(:,1:restart_it)); + + Y = (H(1:restart_it+1, 1:restart_it) \ B (1:restart_it+1)); + + little_res = B(1:restart_it+1) - H(1:restart_it+1, 1:restart_it) * Y(1:restart_it); + prec_res_norm = norm (little_res, 2); + + x = x_old + V(:, 1:restart_it) * Y(1:restart_it); + + resids(iter) = prec_res_norm ; + if (norm (x - x_old, inf) <= eps) + flag = 3; + break + endif + + restart_it++ ; iter++; + endwhile + + if (prec_res_norm > rtol * prec_b_norm) + flag = 0; + endif + + resids = resids(1:iter-1); + itcnt = [floor(maxit/restart), rem(maxit, restart)]; +endfunction + + +%!shared A, b, dim +%! dim = 100; +%!test +%! A = spdiags ([-ones(dim,1) 2*ones(dim,1) ones(dim,1)], [-1:1], dim, dim); +%! b = ones(dim, 1); +%! x = gmres (A, b, 10, 1e-10, dim, @(x) x./diag(A), [], b); +%! assert(x, A\b, 1e-9*norm(x,inf)); +%! +%!test +%! x = gmres (A, b, dim, 1e-10, 1e4, @(x) diag(diag(A))\x, [], b); +%! assert(x, A\b, 1e-7*norm(x,inf)); +%! +%!test +%! A = spdiags ([[1./(2:2:2*(dim-1)) 0]; 1./(1:2:2*dim-1); [0 1./(2:2:2*(dim-1))]]', -1:1, dim, dim); +%! A = A'*A; +%! b = rand (dim, 1); +%! [x, resids] = gmres (@(x) A*x, b, dim, 1e-10, dim, @(x) x./diag(A), [], []); +%! assert(x, A\b, 1e-9*norm(x,inf)) +%! x = gmres (@(x) A*x, b, dim, 1e-10, 1e6, @(x) diag(diag(A))\x, [], []); +%! assert(x, A\b, 1e-9*norm(x,inf)); +%!test +%! x = gmres (@(x) A*x, b, dim, 1e-10, 1e6, @(x) x./diag(A), [], []); +%! assert(x, A\b, 1e-7*norm(x,inf));
--- a/scripts/sparse/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/sparse/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -5,6 +5,7 @@ sparse/cgs.m \ sparse/colperm.m \ sparse/etreeplot.m \ + sparse/gmres.m \ sparse/gplot.m \ sparse/nonzeros.m \ sparse/pcg.m \
--- a/scripts/sparse/nonzeros.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/sparse/nonzeros.m Fri Aug 12 14:16:34 2011 -0400 @@ -27,12 +27,13 @@ print_usage (); endif - [i, j, t] = find (s); + [~, ~, t] = find (s); t = t(:); endfunction + %!assert(nonzeros([1,2;3,0]),[1;3;2]) %!assert(nonzeros([1,2,3,0]),[1;2;3]) %!assert(nonzeros(sparse([1,2;3,0])),[1;3;2])
--- a/scripts/sparse/svds.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/sparse/svds.m Fri Aug 12 14:16:34 2011 -0400 @@ -150,6 +150,8 @@ ## Scale everything by the 1-norm to make things more stable. b = A / max_a; b_opts = opts; + ## Call to eigs is always a symmetric matrix by construction + b_opts.issym = true; b_opts.tol = opts.tol / max_a; b_sigma = sigma; if (!ischar (b_sigma))
--- a/scripts/specfun/bessel.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/specfun/bessel.m Fri Aug 12 14:16:34 2011 -0400 @@ -91,3 +91,4 @@ error ("bessel: you must use besselj, bessely, besseli, or besselk"); endfunction +%!error bessel ()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/specfun/lcm.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,61 @@ +## Copyright (C) 1994-2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Mapping Function} {} lcm (@var{x}, @var{y}) +## @deftypefnx {Mapping Function} {} lcm (@var{x}, @var{y}, @dots{}) +## Compute the least common multiple of @var{x} and @var{y}, +## or of the list of all arguments. All elements must be the same size or +## scalar. +## @seealso{factor, gcd} +## @end deftypefn + +## Author: KH <Kurt.Hornik@wu-wien.ac.at> +## Created: 16 September 1994 +## Adapted-By: jwe + +function l = lcm (varargin) + + if (nargin > 1) + if (common_size (varargin{:}) != 0) + error ("lcm: all args must be of the same size or scalar"); + elseif (! all (cellfun ("isnumeric", varargin))) + error ("lcm: all arguments must be numeric"); + endif + + l = varargin{1}; + for i = 2:nargin + x = varargin{i}; + msk = l == 0 & x == 0; + l .*= x ./ gcd (l, x); + l(msk) = 0; + endfor + else + print_usage (); + endif + +endfunction + +%!assert(lcm (3, 5, 7, 15) == 105); + +%!error lcm (); + +%!test +%! s.a = 1; +%! fail("lcm (s)"); +
--- a/scripts/specfun/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/specfun/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -7,6 +7,7 @@ specfun/factor.m \ specfun/factorial.m \ specfun/isprime.m \ + specfun/lcm.m \ specfun/legendre.m \ specfun/nchoosek.m \ specfun/nthroot.m \
--- a/scripts/specfun/nthroot.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/specfun/nthroot.m Fri Aug 12 14:16:34 2011 -0400 @@ -35,8 +35,9 @@ ## @end group ## @end example ## -## @var{n} must be a scalar. If @var{n} is not an even integer and @var{X} has -## negative entries, an error is produced. +## @var{x} must have all real entries. @var{n} must be a scalar. +## If @var{n} is an even integer and @var{X} has negative entries, an +## error is produced. ## @seealso{realsqrt, sqrt, cbrt} ## @end deftypefn @@ -46,7 +47,11 @@ print_usage (); endif - if (! isscalar (n)) + if (any (iscomplex (x(:)))) + error ("nthroot: X must not contain complex values"); + endif + + if (! isscalar (n) || n == 0) error ("nthroot: N must be a nonzero scalar"); endif @@ -58,7 +63,7 @@ y = 1 ./ nthroot (x, -n); else ## Compute using power. - if (n == round (n) && mod (n, 2) == 1) + if (n == fix (n) && mod (n, 2) == 1) y = abs (x) .^ (1/n) .* sign (x); elseif (any (x(:) < 0)) error ("nthroot: if X contains negative values, N must be an odd integer"); @@ -66,7 +71,7 @@ y = x .^ (1/n); endif - if (finite (n) && n > 0 && n == round (n)) + if (finite (n) && n > 0 && n == fix (n)) ## Correction. y = ((n-1)*y + x ./ (y.^(n-1))) / n; y = merge (finite (y), y, x); @@ -76,8 +81,18 @@ endfunction -%!assert(nthroot(-32,5), -2); -%!assert(nthroot(81,4), 3); -%!assert(nthroot(Inf,4), Inf); -%!assert(nthroot(-Inf,7), -Inf); -%!assert(nthroot(-Inf,-7), 0); +%!assert (nthroot(-32,5), -2); +%!assert (nthroot(81,4), 3); +%!assert (nthroot(Inf,4), Inf); +%!assert (nthroot(-Inf,7), -Inf); +%!assert (nthroot(-Inf,-7), 0); + +%% Test input validation +%!error (nthroot ()) +%!error (nthroot (1)) +%!error (nthroot (1,2,3)) +%!error (nthroot (1+j,2)) +%!error (nthroot (1,[1 2])) +%!error (nthroot (1,0)) +%!error (nthroot (-1,2)) +
--- a/scripts/specfun/perms.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/specfun/perms.m Fri Aug 12 14:16:34 2011 -0400 @@ -63,3 +63,11 @@ endfor endif endfunction + +%!error perms (); +%!error perms (1, 2); + +%!assert (perms ([1,2,3]), [1,2,3;2,1,3;1,3,2;2,3,1;3,1,2;3,2,1]); +%!assert (perms (1:3), perms ([1,2,3])); + +%!assert (perms (int8([1,2,3])), int8([1,2,3;2,1,3;1,3,2;2,3,1;3,1,2;3,2,1]));
--- a/scripts/specfun/primes.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/specfun/primes.m Fri Aug 12 14:16:34 2011 -0400 @@ -92,3 +92,11 @@ endif endfunction + +%!error primes (); +%!error primes (1, 2); + +%!assert (size (primes (350)), [1, 70]); +%!assert (size (primes (350)), [1, 70]); + +%!assert (primes (357)(end), 353);
--- a/scripts/special-matrix/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/special-matrix/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -8,7 +8,6 @@ special-matrix/magic.m \ special-matrix/pascal.m \ special-matrix/rosser.m \ - special-matrix/sylvester_matrix.m \ special-matrix/toeplitz.m \ special-matrix/vander.m \ special-matrix/wilkinson.m
--- a/scripts/special-matrix/sylvester_matrix.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -## Copyright (C) 1996-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} sylvester_matrix (@var{k}) -## Return the Sylvester matrix of order -## @tex -## $n = 2^k$. -## @end tex -## @ifnottex -## n = 2^@var{k}. -## @end ifnottex -## -## @seealso{toeplitz, hankel} -## @end deftypefn - -## Author: jwe - -function retval = sylvester_matrix (k) - - if (nargin != 1) - print_usage (); - endif - - if (isscalar (k)) - if (k < 1) - retval = 1; - else - tmp = sylvester_matrix (k-1); - retval = [tmp, tmp; tmp, -tmp]; - endif - else - error ("sylvester_matrix: expecting scalar argument"); - endif - -endfunction - -%!assert((sylvester_matrix (1) == [1, 1; 1, -1] -%! && (sylvester_matrix (2) -%! == [1, 1, 1, 1; 1, -1, 1, -1; 1, 1, -1, -1; 1, -1, -1, 1]))); - -%!error sylvester_matrix ([1, 2; 3, 4]); - -%!error sylvester_matrix (); - -%!error sylvester_matrix (1, 2); -
--- a/scripts/startup/__finish__.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/startup/__finish__.m Fri Aug 12 14:16:34 2011 -0400 @@ -36,3 +36,5 @@ endfunction +## No test needed for internal helper function. +%!assert (1)
--- a/scripts/statistics/base/center.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/center.m Fri Aug 12 14:16:34 2011 -0400 @@ -23,7 +23,7 @@ ## If @var{x} is a vector, subtract its mean. ## If @var{x} is a matrix, do the above for each column. ## If the optional argument @var{dim} is given, operate along this dimension. -## @seealso{studentize} +## @seealso{zscore} ## @end deftypefn ## Author: KH <Kurt.Hornik@wu-wien.ac.at> @@ -35,7 +35,7 @@ print_usage (); endif - if (!isnumeric (x)) + if (! (isnumeric (x) || islogical (x))) error ("center: X must be a numeric vector or matrix"); endif @@ -47,10 +47,7 @@ sz = size (x); if (nargin != 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -58,25 +55,28 @@ endif endif - n = size (x, dim); + n = sz(dim); if (n == 0) retval = x; else - retval = bsxfun (@minus, x, sum (x, dim) / n); + retval = bsxfun (@minus, x, mean (x, dim)); endif endfunction %!assert(center ([1,2,3]), [-1,0,1]) +%!assert(center (single([1,2,3])), single([-1,0,1])) %!assert(center (int8 ([1,2,3])), [-1,0,1]) +%!assert(center (logical ([1, 0, 0, 1])), [0.5, -0.5, -0.5, 0.5]) %!assert(center (ones (3,2,0,2)), zeros (3,2,0,2)) +%!assert(center (ones (3,2,0,2, 'single')), zeros (3,2,0,2, 'single')) %!assert(center (magic (3)), [3,-4,1;-2,0,2;-1,4,-3]) +%!assert(center ([1 2 3; 6 5 4], 2), [-1 0 1; 1 0 -1]) %% Test input validation %!error center () %!error center (1, 2, 3) -%!error center ([true true]) %!error center (1, ones(2,2)) %!error center (1, 1.5) %!error center (1, 0)
--- a/scripts/statistics/base/cor.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -## Copyright (C) 1995-2011 Kurt Hornik -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} cor (@var{x}) -## @deftypefnx {Function File} {} cor (@var{x}, @var{y}) -## Compute matrix of correlation coefficients. -## -## This is an alias for @code{corrcoef}. -## @seealso{corrcoef} -## @end deftypefn - -function retval = cor (x, y = x) - - if (nargin < 1 || nargin > 2) - print_usage (); - endif - - retval = corrcoef (x, y); - -endfunction - -%!test -%! x = rand (10, 2); -%! assert (cor (x), corrcoef (x), 5*eps); -%! assert (cor (x(:,1), x(:,2)) == corrcoef (x(:,1), x(:,2))); - -%% Test input validation -%!error corrcoef (); -%!error corrcoef (1, 2, 3); -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/statistics/base/corr.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,112 @@ +## Copyright (C) 1996-2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} corr (@var{x}) +## @deftypefnx {Function File} {} corr (@var{x}, @var{y}) +## Compute matrix of correlation coefficients. +## +## If each row of @var{x} and @var{y} is an observation and each column is +## a variable, then the @w{(@var{i}, @var{j})-th} entry of +## @code{corr (@var{x}, @var{y})} is the correlation between the +## @var{i}-th variable in @var{x} and the @var{j}-th variable in @var{y}. +## @tex +## $$ +## {\rm corr}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)} +## $$ +## @end tex +## @ifnottex +## +## @example +## corr(x,y) = cov(x,y)/(std(x)*std(y)) +## @end example +## +## @end ifnottex +## If called with one argument, compute @code{corr (@var{x}, @var{x})}, +## the correlation between the columns of @var{x}. +## @seealso{cov} +## @end deftypefn + +## Author: Kurt Hornik <hornik@wu-wien.ac.at> +## Created: March 1993 +## Adapted-By: jwe + +function retval = corr (x, y = []) + + if (nargin < 1 || nargin > 2) + print_usage (); + endif + + ## Input validation is done by cov.m. Don't repeat tests here + + ## Special case, scalar is always 100% correlated with itself + if (isscalar (x)) + if (isa (x, 'single')) + retval = single (1); + else + retval = 1; + endif + return; + endif + + ## No check for division by zero error, which happens only when + ## there is a constant vector and should be rare. + if (nargin == 2) + c = cov (x, y); + s = std (x)' * std (y); + retval = c ./ s; + else + c = cov (x); + s = sqrt (diag (c)); + retval = c ./ (s * s'); + endif + +endfunction + + +%!test +%! x = rand (10); +%! cc1 = corr (x); +%! cc2 = corr (x, x); +%! assert (size (cc1) == [10, 10] && size (cc2) == [10, 10]); +%! assert (cc1, cc2, sqrt (eps)); + +%!test +%! x = [1:3]'; +%! y = [3:-1:1]'; +%! assert (corr (x,y), -1, 5*eps) +%! assert (corr (x,flipud (y)), 1, 5*eps) +%! assert (corr ([x, y]), [1 -1; -1 1], 5*eps) + +%!test +%! x = single ([1:3]'); +%! y = single ([3:-1:1]'); +%! assert (corr (x,y), single (-1), 5*eps) +%! assert (corr (x,flipud (y)), single (1), 5*eps) +%! assert (corr ([x, y]), single ([1 -1; -1 1]), 5*eps) + +%!assert (corr (5), 1); +%!assert (corr (single(5)), single(1)); + +%% Test input validation +%!error corr (); +%!error corr (1, 2, 3); +%!error corr ([1; 2], ["A", "B"]); +%!error corr (ones (2,2,2)); +%!error corr (ones (2,2), ones (2,2,2)); +
--- a/scripts/statistics/base/corrcoef.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,98 +0,0 @@ -## Copyright (C) 1996-2011 John W. Eaton -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} corrcoef (@var{x}) -## @deftypefnx {Function File} {} corrcoef (@var{x}, @var{y}) -## Compute matrix of correlation coefficients. -## -## If each row of @var{x} and @var{y} is an observation and each column is -## a variable, then the @w{(@var{i}, @var{j})-th} entry of -## @code{corrcoef (@var{x}, @var{y})} is the correlation between the -## @var{i}-th variable in @var{x} and the @var{j}-th variable in @var{y}. -## @tex -## $$ -## {\rm corrcoef}(x,y) = {{\rm cov}(x,y) \over {\rm std}(x) {\rm std}(y)} -## $$ -## @end tex -## @ifnottex -## -## @example -## corrcoef(x,y) = cov(x,y)/(std(x)*std(y)) -## @end example -## -## @end ifnottex -## If called with one argument, compute @code{corrcoef (@var{x}, @var{x})}, -## the correlation between the columns of @var{x}. -## @seealso{cov} -## @end deftypefn - -## Author: Kurt Hornik <hornik@wu-wien.ac.at> -## Created: March 1993 -## Adapted-By: jwe - -function retval = corrcoef (x, y = []) - - if (nargin < 1 || nargin > 2) - print_usage (); - endif - - if (! (isnumeric (x) && isnumeric (y))) - error ("corrcoef: X and Y must be numeric matrices or vectors"); - endif - - if (ndims (x) != 2 || ndims (y) != 2) - error ("corrcoef: X and Y must be 2-D matrices or vectors"); - endif - - if (isscalar (x)) - retval = 1; - return; - endif - - ## No check for division by zero error, which happens only when - ## there is a constant vector and should be rare. - if (nargin == 2) - c = cov (x, y); - s = std (x)' * std (y); - retval = c ./ s; - else - c = cov (x); - s = sqrt (diag (c)); - retval = c ./ (s * s'); - endif - -endfunction - -%!test -%! x = rand (10); -%! cc1 = corrcoef (x); -%! cc2 = corrcoef (x, x); -%! assert((size (cc1) == [10, 10] && size (cc2) == [10, 10] -%! && abs (cc1 - cc2) < sqrt (eps))); - -%!assert(corrcoef (5), 1); - -%% Test input validation -%!error corrcoef (); -%!error corrcoef (1, 2, 3); -%!error corrcoef ([true, true]); -%!error corrcoef ([1, 2], [true, true]); -%!error corrcoef (ones (2,2,2)); -%!error corrcoef (ones (2,2), ones (2,2,2)); -
--- a/scripts/statistics/base/cov.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/cov.m Fri Aug 12 14:16:34 2011 -0400 @@ -55,7 +55,7 @@ ## @item 1: ## normalize with @math{N}, this provides the second moment around the mean ## @end table -## @seealso{corrcoef, cor} +## @seealso{corr} ## @end deftypefn ## Author: KH <Kurt.Hornik@wu-wien.ac.at> @@ -67,7 +67,8 @@ print_usage (); endif - if (! (isnumeric (x) && isnumeric (y))) + if ( ! (isnumeric (x) || islogical (x)) + || ! (isnumeric (y) || islogical (y))) error ("cov: X and Y must be numeric matrices or vectors"); endif @@ -75,7 +76,7 @@ error ("cov: X and Y must be 2-D matrices or vectors"); endif - if (nargin == 2 && isscalar(y)) + if (nargin == 2 && isscalar (y)) opt = y; endif @@ -83,22 +84,27 @@ error ("cov: normalization OPT must be 0 or 1"); endif + ## Special case, scalar has zero covariance if (isscalar (x)) - c = 0; + if (isa (x, 'single')) + c = single (0); + else + c = 0; + endif return; endif - if (rows (x) == 1) - x = x'; + if (isrow (x)) + x = x.'; endif n = rows (x); - if (nargin == 1 || isscalar(y)) + if (nargin == 1 || isscalar (y)) x = center (x, 1); c = conj (x' * x / (n - 1 + opt)); else - if (rows (y) == 1) - y = y'; + if (isrow (y)) + y = y.'; endif if (rows (y) != n) error ("cov: X and Y must have the same number of observations"); @@ -110,17 +116,36 @@ endfunction + %!test %! x = rand (10); %! cx1 = cov (x); %! cx2 = cov (x, x); -%! assert(size (cx1) == [10, 10] && size (cx2) == [10, 10] && norm(cx1-cx2) < 1e1*eps); +%! assert(size (cx1) == [10, 10] && size (cx2) == [10, 10]); +%! assert(cx1, cx2, 1e1*eps); + +%!test +%! x = [1:3]'; +%! y = [3:-1:1]'; +%! assert (cov (x,y), -1, 5*eps) +%! assert (cov (x,flipud (y)), 1, 5*eps) +%! assert (cov ([x, y]), [1 -1; -1 1], 5*eps) + +%!test +%! x = single ([1:3]'); +%! y = single ([3:-1:1]'); +%! assert (cov (x,y), single (-1), 5*eps) +%! assert (cov (x,flipud (y)), single (1), 5*eps) +%! assert (cov ([x, y]), single ([1 -1; -1 1]), 5*eps) %!test %! x = [1:5]; %! c = cov (x); -%! assert(isscalar (c)); -%! assert(c, 2.5); +%! assert (isscalar (c)); +%! assert (c, 2.5); + +%!assert(cov (5), 0); +%!assert(cov (single(5)), single(0)); %!test %! x = [1:5]; @@ -129,13 +154,10 @@ %! c = cov (x, 1); %! assert(c, 2); -%!assert(cov (5), 0); - %% Test input validation %!error cov (); %!error cov (1, 2, 3, 4); -%!error cov ([true, true]); -%!error cov ([1, 2], [true, true]); +%!error cov ([1; 2], ["A", "B"]); %!error cov (ones (2,2,2)); %!error cov (ones (2,2), ones (2,2,2)); %!error cov (1, 3);
--- a/scripts/statistics/base/cut.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -## Copyright (C) 1996-2011 Kurt Hornik -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} cut (@var{x}, @var{breaks}) -## Create categorical data from numerical or continuous data by -## cutting into intervals. -## -## If @var{breaks} is a scalar, the data is cut into that many -## equal-width intervals. If @var{breaks} is a vector of break points, -## the category has @code{length (@var{breaks}) - 1} groups. -## -## The returned value is a vector of the same size as @var{x} telling -## which group each point in @var{x} belongs to. Groups are labelled -## from 1 to the number of groups; points outside the range of -## @var{breaks} are labelled by @code{NaN}. -## @seealso{histc} -## @end deftypefn - -## Author: KH <Kurt.Hornik@wu-wien.ac.at> -## Description: Cut data into intervals - -function group = cut (x, breaks) - - if (nargin != 2) - print_usage (); - endif - - if (!isvector (x)) - error ("cut: X must be a vector"); - endif - if isscalar (breaks) - breaks = linspace (min (x), max (x), breaks + 1); - breaks(1) = breaks(1) - 1; - elseif isvector (breaks) - breaks = sort (breaks); - else - error ("cut: BREAKS must be a scalar or vector"); - endif - - group = NaN (size (x)); - m = length (breaks); - if any (k = find ((x >= min (breaks)) & (x < max (breaks)))) - n = length (k); - group(k) = sum ((ones (m, 1) * reshape (x(k), 1, n)) - >= (reshape (breaks, m, 1) * ones (1, n))); - endif - -endfunction
--- a/scripts/statistics/base/gls.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/gls.m Fri Aug 12 14:16:34 2011 -0400 @@ -82,10 +82,21 @@ if (rx != ry) error ("gls: number of rows of X and Y must be equal"); endif - if (!issquare(o) || ro != ry*cy) + if (!issquare (o) || ro != ry*cy) error ("gls: matrix O must be square matrix with rows = rows (Y) * cols (Y)"); endif + if (isinteger (x)) + x = double (x); + endif + if (isinteger (y)) + y = double (y); + endif + if (isinteger (o)) + o = double (o); + endif + + ## Start of algorithm o = o^(-1/2); z = kron (eye (cy), x); z = o * z; @@ -116,7 +127,7 @@ %! y = 3*x + 2; %! x = [x, ones(5,1)]; %! o = diag (ones (5,1)); -%! assert (gls (y,x,o), [3; 2], 50*eps) +%! assert (gls (y,x,o), [3; 2], 50*eps); %% Test input validation %!error gls ()
--- a/scripts/statistics/base/histc.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/histc.m Fri Aug 12 14:16:34 2011 -0400 @@ -61,7 +61,7 @@ error ("histc: EDGES must be real-valued, not complex"); else ## Make sure 'edges' is sorted - edges = edges (:); + edges = edges(:); if (!issorted (edges) || edges(1) > edges(end)) warning ("histc: edge values not sorted on input"); edges = sort (edges); @@ -72,10 +72,7 @@ sz = size (x); if (nargin < 3) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -103,25 +100,25 @@ ## Prepare indices idx1 = cell (1, dim-1); for k = 1:length (idx1) - idx1 {k} = 1:sz(k); + idx1{k} = 1:sz(k); endfor idx2 = cell (length (sz) - dim); for k = 1:length (idx2) - idx2 {k} = 1:sz(k+dim); + idx2{k} = 1:sz(k+dim); endfor ## Compute the histograms for k = 1:num_edges-1 b = (edges (k) <= x & x < edges (k+1)); - n (idx1 {:}, k, idx2 {:}) = sum (b, dim); + n(idx1{:}, k, idx2{:}) = sum (b, dim); if (nargout > 1) - idx (b) = k; + idx(b) = k; endif endfor b = (x == edges (end)); - n (idx1 {:}, num_edges, idx2 {:}) = sum (b, dim); + n(idx1{:}, num_edges, idx2{:}) = sum (b, dim); if (nargout > 1) - idx (b) = num_edges; + idx(b) = num_edges; endif else @@ -160,6 +157,7 @@ endfunction + %!test %! x = linspace (0, 10, 1001); %! n = histc (x, 0:10);
--- a/scripts/statistics/base/iqr.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/iqr.m Fri Aug 12 14:16:34 2011 -0400 @@ -39,7 +39,7 @@ print_usage (); endif - if (!(ismatrix (x) && isnumeric (x)) || isscalar(x)) + if (! (isnumeric (x) || islogical (x))) error ("iqr: X must be a numeric vector or matrix"); endif @@ -48,10 +48,7 @@ nel = numel (x); if (nargin != 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -60,27 +57,33 @@ endif ## This code is a bit heavy, but is needed until empirical_inv - ## takes other than vector arguments. - c = sz(dim); + ## can take a matrix, rather than just a vector argument. + n = sz(dim); sz(dim) = 1; - y = zeros (sz); + if (isa (x, 'single')) + y = zeros (sz, 'single'); + else + y = zeros (sz); + endif stride = prod (sz(1:dim-1)); - for i = 1 : nel / c; + for i = 1 : nel / n; offset = i; offset2 = 0; while (offset > stride) offset -= stride; offset2++; endwhile - offset += offset2 * stride * c; - rng = [0 : c-1] * stride + offset; + offset += offset2 * stride * n; + rng = [0 : n-1] * stride + offset; - y (i) = empirical_inv (3/4, x(rng)) - empirical_inv (1/4, x(rng)); + y(i) = diff (empirical_inv ([1/4, 3/4], x(rng))); endfor endfunction + %!assert (iqr (1:101), 50); +%!assert (iqr (single(1:101)), single(50)); %%!test %%! x = [1:100]; @@ -90,5 +93,6 @@ %!error iqr (); %!error iqr (1, 2, 3); %!error iqr (1); -%!error iqr ([true, true]); +%!error iqr (['A'; 'B']); %!error iqr (1:10, 3); +
--- a/scripts/statistics/base/kendall.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/kendall.m Fri Aug 12 14:16:34 2011 -0400 @@ -74,7 +74,8 @@ print_usage (); endif - if (! (isnumeric (x) && isnumeric (y))) + if ( ! (isnumeric (x) || islogical (x)) + || ! (isnumeric (y) || islogical (y))) error ("kendall: X and Y must be numeric matrices or vectors"); endif @@ -82,14 +83,14 @@ error ("kendall: X and Y must be 2-D matrices or vectors"); endif - if (rows (x) == 1) - x = x'; + if (isrow (x)) + x = x.'; endif [n, c] = size (x); if (nargin == 2) - if (rows (y) == 1) - y = y'; + if (isrow (y)) + y = y.'; endif if (rows (y) != n) error ("kendall: X and Y must have the same number of observations"); @@ -98,22 +99,36 @@ endif endif + if (isa (x, 'single') || isa (y, 'single')) + cls = 'single'; + else + cls = 'double'; + endif r = ranks (x); - m = sign (kron (r, ones (n, 1)) - kron (ones (n, 1), r)); - tau = corrcoef (m); + m = sign (kron (r, ones (n, 1, cls)) - kron (ones (n, 1, cls), r)); + tau = corr (m); if (nargin == 2) - tau = tau (1 : c, (c + 1) : columns (x)); + tau = tau(1 : c, (c + 1) : columns (x)); endif endfunction +%!test +%! x = [1:2:10]; +%! y = [100:10:149]; +%! assert (kendall (x,y), 1, 5*eps); +%! assert (kendall (x,fliplr (y)), -1, 5*eps); + +%!assert (kendall (logical(1)), 1); +%!assert (kendall (single(1)), single(1)); + %% Test input validation %!error kendall (); %!error kendall (1, 2, 3); -%!error kendall ([true, true]); -%!error kendall (ones(1,2), [true, true]); +%!error kendall (['A'; 'B']); +%!error kendall (ones(2,1), ['A'; 'B']); %!error kendall (ones (2,2,2)); %!error kendall (ones (2,2), ones (2,2,2)); %!error kendall (ones (2,2), ones (3,2));
--- a/scripts/statistics/base/kurtosis.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/kurtosis.m Fri Aug 12 14:16:34 2011 -0400 @@ -54,7 +54,7 @@ print_usage (); endif - if (!isnumeric (x)) + if (! (isnumeric (x) || islogical (x))) error ("kurtosis: X must be a numeric vector or matrix"); endif @@ -62,10 +62,7 @@ sz = size (x); if (nargin != 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -73,16 +70,14 @@ endif endif - c = sz(dim); + n = sz(dim); sz(dim) = 1; - idx = ones (1, nd); - idx(dim) = c; - x = x - repmat (mean (x, dim), idx); + x = center (x, dim); # center also promotes integer to double for next line retval = zeros (sz, class (x)); s = std (x, [], dim); + idx = find (s > 0); x = sum (x.^4, dim); - ind = find (s > 0); - retval(ind) = x(ind) ./ (c * s(ind) .^ 4) - 3; + retval(idx) = x(idx) ./ (n * s(idx) .^ 4) - 3; endfunction @@ -90,12 +85,14 @@ %!test %! x = [-1; 0; 0; 0; 1]; %! y = [x, 2*x]; -%! assert(all (abs (kurtosis (y) - [-1.4, -1.4]) < sqrt (eps))); +%! assert (kurtosis (y), [-1.4, -1.4], sqrt (eps)); + +%!assert (kurtosis (single(1)), single(0)); %% Test input validation %!error kurtosis () %!error kurtosis (1, 2, 3) -%!error kurtosis (true(1,2)) +%!error kurtosis (['A'; 'B']) %!error kurtosis (1, ones(2,2)) %!error kurtosis (1, 1.5) %!error kurtosis (1, 0)
--- a/scripts/statistics/base/logit.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/logit.m Fri Aug 12 14:16:34 2011 -0400 @@ -47,6 +47,7 @@ endfunction + %!test %! p = [0.01:0.01:0.99]; %! assert(logit (p), log (p ./ (1-p)), 25*eps)
--- a/scripts/statistics/base/mahalanobis.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/mahalanobis.m Fri Aug 12 14:16:34 2011 -0400 @@ -34,7 +34,8 @@ print_usage (); endif - if (! (isnumeric (x) && isnumeric (y))) + if ( ! (isnumeric (x) || islogical (x)) + || ! (isnumeric (y) || islogical (y))) error ("mahalanobis: X and Y must be numeric matrices or vectors"); endif @@ -49,11 +50,16 @@ error ("mahalanobis: X and Y must have the same number of columns"); endif + if (isinteger (x)) + x = double (x); + endif + xm = mean (x); ym = mean (y); - x = x - ones (xr, 1) * xm; - y = y - ones (yr, 1) * ym; + ## Center data by subtracting means + x = bsxfun (@minus, x, xm); + y = bsxfun (@minus, y, ym); w = (x' * x + y' * y) / (xr + yr - 2); @@ -63,11 +69,12 @@ endfunction + %% Test input validation %!error mahalanobis (); %!error mahalanobis (1, 2, 3); -%!error mahalanobis ([true], [true]); -%!error mahalanobis ([1, 2], [true, true]); +%!error mahalanobis ('A', 'B'); +%!error mahalanobis ([1, 2], ['A', 'B']); %!error mahalanobis (ones (2,2,2)); %!error mahalanobis (ones (2,2), ones (2,2,2)); %!error mahalanobis (ones (2,2), ones (2,3));
--- a/scripts/statistics/base/mean.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/mean.m Fri Aug 12 14:16:34 2011 -0400 @@ -69,15 +69,15 @@ error ("mean: X must be a numeric vector or matrix"); endif - need_dim = 0; + need_dim = false; if (nargin == 1) opt = "a"; - need_dim = 1; + need_dim = true; elseif (nargin == 2) if (ischar (opt1)) opt = opt1; - need_dim = 1; + need_dim = true; else dim = opt1; opt = "a"; @@ -100,22 +100,15 @@ sz = size (x); if (need_dim) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; + (dim = find (sz > 1, 1)) || (dim = 1); + else + if (!(isscalar (dim) && dim == fix (dim)) + || !(1 <= dim && dim <= nd)) + error ("mean: DIM must be an integer and a valid dimension"); endif endif - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) - error ("mean: DIM must be an integer and a valid dimension"); - endif - - if (dim > nd) - n = 1; - else - n = sz(dim); - endif + n = sz(dim); if (strcmp (opt, "a")) y = sum (x, dim) / n; @@ -129,6 +122,7 @@ endfunction + %!test %! x = -10:10; %! y = x'; @@ -137,9 +131,12 @@ %! assert(mean (y) == 0); %! assert(mean (z) == [0, 10]); +%!assert(mean (magic(3), 1), [5, 5, 5]); +%!assert(mean (magic(3), 2), [5; 5; 5]); %!assert(mean ([2 8], 'g'), 4); %!assert(mean ([4 4 2], 'h'), 3); %!assert(mean (logical ([1 0 1 1])), 0.75); +%!assert(mean (single ([1 0 1 1])), single (0.75)); %% Test input validation %!error mean ();
--- a/scripts/statistics/base/meansq.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/meansq.m Fri Aug 12 14:16:34 2011 -0400 @@ -52,7 +52,7 @@ print_usage (); endif - if (!isnumeric (x)) + if (! (isnumeric (x) || islogical (x))) error ("mean: X must be a numeric vector or matrix"); endif @@ -60,29 +60,28 @@ sz = size (x); if (nargin < 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; + (dim = find (sz > 1, 1)) || (dim = 1); + else + if (!(isscalar (dim) && dim == fix (dim)) + || !(1 <= dim && dim <= nd)) + error ("mean: DIM must be an integer and a valid dimension"); endif endif - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) - error ("mean: DIM must be an integer and a valid dimension"); - endif - - y = sumsq (x, dim) / size (x, dim); + y = sumsq (x, dim) / sz(dim); endfunction -%!assert(meansq (1:5), 11) -%!assert(meansq (magic (4)), [94.5, 92.5, 92.5, 94.5]) +%!assert(meansq (1:5), 11); +%!assert(meansq (single(1:5)), single(11)); +%!assert(meansq (magic (4)), [94.5, 92.5, 92.5, 94.5]); +%!assert(meansq (magic (4), 2), [109.5; 77.5; 77.5; 109.5]); %% Test input validation %!error meansq () %!error meansq (1, 2, 3) -%!error kurtosis ([true true]) +%!error meansq (['A'; 'B']); %!error meansq (1, ones(2,2)) %!error meansq (1, 1.5) %!error meansq (1, 0)
--- a/scripts/statistics/base/median.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/median.m Fri Aug 12 14:16:34 2011 -0400 @@ -55,18 +55,19 @@ print_usage (); endif - if (!isnumeric (x)) + if (! (isnumeric (x) || islogical (x))) error ("median: X must be a numeric vector or matrix"); endif + if (isempty (x)) + error ("median: X cannot be an empty matrix"); + endif + nd = ndims (x); sz = size (x); - if (nargin != 2) + if (nargin < 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -74,22 +75,19 @@ endif endif - if (numel (x) > 0) - n = size (x, dim); - k = floor ((n+1) / 2); - if (mod (n, 2) == 1) - retval = nth_element (x, k, dim); - else - retval = mean (nth_element (x, k:k+1, dim), dim); - endif - ## Inject NaNs where needed, to be consistent with Matlab. - retval(any (isnan (x), dim)) = NaN; + n = sz(dim); + k = floor ((n+1) / 2); + if (mod (n, 2) == 1) + retval = nth_element (x, k, dim); else - error ("median: invalid matrix argument"); + retval = mean (nth_element (x, k:k+1, dim), dim); endif + ## Inject NaNs where needed, to be consistent with Matlab. + retval(any (isnan (x), dim)) = NaN; endfunction + %!test %! x = [1, 2, 3, 4, 5, 6]; %! x2 = x'; @@ -101,13 +99,14 @@ %! assert(median ([x2, 2*x2]) == [3.5, 7]); %! assert(median ([y2, 3*y2]) == [4, 12]); +%!assert(median (single([1,2,3])), single(2)); %!assert(median ([1,2,NaN;4,5,6;NaN,8,9]), [NaN, 5, NaN]); %% Test input validation %!error median (); %!error median (1, 2, 3); %!error median ({1:5}); -%!error median (true(1,5)); +%!error median (['A'; 'B']); %!error median (1, ones(2,2)); %!error median (1, 1.5); %!error median (1, 0);
--- a/scripts/statistics/base/mode.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/mode.m Fri Aug 12 14:16:34 2011 -0400 @@ -39,18 +39,15 @@ print_usage (); endif - if (!isnumeric(x)) + if (! (isnumeric (x) || islogical (x))) error ("mode: X must be a numeric vector or matrix"); endif nd = ndims (x); sz = size (x); - if (nargin != 2) + if (nargin < 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == round (dim)) || !(1 <= dim && dim <= nd)) @@ -78,11 +75,11 @@ t = cat (dim, true (sz2), diff (xs, 1, dim) != 0); if (dim != 1) - t2 (permute (t != 0, perm)) = diff ([find(permute (t, perm))(:); prod(sz)+1]); + t2(permute (t != 0, perm)) = diff ([find(permute (t, perm))(:); prod(sz)+1]); f = max (ipermute (t2, perm), [], dim); xs = permute (xs, perm); else - t2 (t) = diff ([find(t)(:); prod(sz)+1]); + t2(t) = diff ([find(t)(:); prod(sz)+1]); f = max (t2, [], dim); endif @@ -90,14 +87,15 @@ if (issparse (x)) m = sparse (sz2(1), sz2(2)); else - m = zeros (sz2); + m = zeros (sz2, class (x)); endif for i = 1 : prod (sz2) - c{i} = xs (t2 (:, i) == f(i), i); - m (i) = c{i}(1); + c{i} = xs(t2(:, i) == f(i), i); + m(i) = c{i}(1); endfor endfunction + %!test %! [m, f, c] = mode (toeplitz (1:5)); %! assert (m, [1,2,2,2,1]); @@ -114,15 +112,19 @@ %! [m2, f2, c2] = mode (full (a)); %! assert (m, sparse (m2)); %! assert (f, sparse (f2)); -%! assert (c, cellfun (@(x) sparse (0), c2, 'uniformoutput', false)); +%! c_exp(1:length(a)) = { sparse (0) }; +%! assert (c ,c_exp); +%! assert (c2,c_exp ); -%!assert(mode([2,3,1,2,3,4],1),[2,3,1,2,3,4]) -%!assert(mode([2,3,1,2,3,4],2),2) -%!assert(mode([2,3,1,2,3,4]),2) +%!assert(mode ([2,3,1,2,3,4],1),[2,3,1,2,3,4]); +%!assert(mode ([2,3,1,2,3,4],2),2); +%!assert(mode ([2,3,1,2,3,4]),2); +%!assert(mode (single([2,3,1,2,3,4])), single(2)); +%!assert(mode (int8([2,3,1,2,3,4])), int8(2)); -%!assert(mode([2;3;1;2;3;4],1),2) -%!assert(mode([2;3;1;2;3;4],2),[2;3;1;2;3;4]) -%!assert(mode([2;3;1;2;3;4]),2) +%!assert(mode ([2;3;1;2;3;4],1),2); +%!assert(mode ([2;3;1;2;3;4],2),[2;3;1;2;3;4]); +%!assert(mode ([2;3;1;2;3;4]),2); %!shared x %! x(:,:,1) = toeplitz (1:3); @@ -157,7 +159,7 @@ %!error mode () %!error mode (1, 2, 3) %!error mode ({1 2 3}) -%!error mode (true(1,3)) +%!error mode (['A'; 'B']) %!error mode (1, ones(2,2)) %!error mode (1, 1.5) %!error mode (1, 0)
--- a/scripts/statistics/base/module.mk Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/module.mk Fri Aug 12 14:16:34 2011 -0400 @@ -3,10 +3,8 @@ statistics_base_FCN_FILES = \ statistics/base/center.m \ statistics/base/cloglog.m \ - statistics/base/cor.m \ - statistics/base/corrcoef.m \ + statistics/base/corr.m \ statistics/base/cov.m \ - statistics/base/cut.m \ statistics/base/gls.m \ statistics/base/histc.m \ statistics/base/iqr.m \ @@ -33,9 +31,9 @@ statistics/base/spearman.m \ statistics/base/statistics.m \ statistics/base/std.m \ - statistics/base/studentize.m \ statistics/base/table.m \ - statistics/base/var.m + statistics/base/var.m \ + statistics/base/zscore.m FCN_FILES += $(statistics_base_FCN_FILES)
--- a/scripts/statistics/base/moment.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/moment.m Fri Aug 12 14:16:34 2011 -0400 @@ -110,27 +110,27 @@ function m = moment (x, p, opt1, opt2) - if ((nargin < 2) || (nargin > 4)) + if (nargin < 2 || nargin > 4) print_usage (); endif - if (!isnumeric(x) || isempty(x) ) + if (!(isnumeric (x) || islogical (x)) || isempty (x)) error ("moment: X must be a non-empty numeric matrix or vector"); endif - if (!(isnumeric(p) && isscalar(p))) + if (! (isnumeric (p) && isscalar (p))) error ("moment: P must be a numeric scalar"); endif - need_dim = 0; + need_dim = false; if (nargin == 2) type = ""; - need_dim = 1; + need_dim = true; elseif (nargin == 3) if (ischar (opt1)) type = opt1; - need_dim = 1; + need_dim = true; else dim = opt1; type = ""; @@ -151,10 +151,7 @@ sz = size (x); if (need_dim) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -164,10 +161,8 @@ n = sz(dim); - if any (type == "c") - rng = ones (1, length (sz)); - rng(dim) = sz(dim); - x = x - repmat (sum (x, dim), rng) / n; + if (any (type == "c")) + x = center (x, dim); endif if any (type == "a") x = abs (x); @@ -178,11 +173,21 @@ endfunction +%!test +%! x = rand (10); +%! assert (moment (x,1), mean (x), 1e1*eps); +%! assert (moment (x,2), meansq (x), 1e1*eps); +%! assert (moment (x,1,2), mean (x,2), 1e1*eps); +%! assert (moment (x,1,'c'), mean (center (x)), 1e1*eps); +%! assert (moment (x,1,'a'), mean (abs (x)), 1e1*eps); + +%!assert (moment (single([1 2 3]),1), single(2)); + %% Test input validation %!error moment () %!error moment (1) %!error moment (1, 2, 3, 4, 5) -%!error moment ([true true], 2) +%!error moment (['A'; 'B'], 2) %!error moment (ones(2,0,3), 2) %!error moment (1, true) %!error moment (1, ones(2,2))
--- a/scripts/statistics/base/ols.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/ols.m Fri Aug 12 14:16:34 2011 -0400 @@ -100,6 +100,14 @@ error ("ols: number of rows of X and Y must be equal"); endif + if (isinteger (x)) + x = double (x); + endif + if (isinteger (y)) + y = double (y); + endif + + ## Start of algorithm z = x' * x; rnk = rank (z); @@ -118,6 +126,7 @@ endfunction + %!test %! x = [1:5]'; %! y = 3*x + 2;
--- a/scripts/statistics/base/ppplot.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/ppplot.m Fri Aug 12 14:16:34 2011 -0400 @@ -77,6 +77,7 @@ endfunction + %% Test input validation %!error ppplot (); %!error ppplot (ones(2,2));
--- a/scripts/statistics/base/prctile.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/prctile.m Fri Aug 12 14:16:34 2011 -0400 @@ -40,52 +40,48 @@ ## Author: Ben Abbott <bpabbott@mac.com> ## Description: Matlab style prctile function. -function q = prctile (x, p, dim) +function q = prctile (x, p = [], dim) if (nargin < 1 || nargin > 3) print_usage (); endif - if (!isnumeric(x)) + if (! (isnumeric (x) || islogical (x))) error ("prctile: X must be a numeric vector or matrix"); endif - if (!isnumeric(p)) - error ("prctile: P must be a numeric vector"); + + if (isempty (p)) + p = [0, 25, 50, 75, 100]; endif - if (nargin == 1) - p = [0, 25, 50, 75, 100]; + if (! (isnumeric (p) && isvector (p))) + error ("prctile: P must be a numeric vector"); endif nd = ndims (x); if (nargin == 2) if (nd == 2) - ## If a matrix or vector, use the 1st dimension. + ## If a matrix or vector, always use 1st dimension. dim = 1; else ## If an N-d array, find the first non-singleton dimension. - dim = find (size(v) > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); endif else - if (!(isscalar (dim) && dim == fix (dim)) || - !(1 <= dim && dim <= nd)) + if (!(isscalar (dim) && dim == fix (dim)) + || !(1 <= dim && dim <= nd)) error ("prctile: DIM must be an integer and a valid dimension"); endif endif ## Convert from percent to decimal. - p = p / 100; + p /= 100; - ## The 5th method is compatible with Matlab. - method = 5; - - q = quantile (x, p, dim, method); + q = quantile (x, p, dim); endfunction + %!test %! pct = 50; %! q = prctile (1:4, pct, 1); @@ -171,8 +167,9 @@ %% Test input validation %!error prctile () %!error prctile (1, 2, 3, 4) -%!error prctile ([true, false], 10) +%!error prctile (['A'; 'B'], 10) %!error prctile (1:10, [true, false]) +%!error prctile (1:10, ones (2,2)) %!error prctile (1, 1, 1.5) %!error prctile (1, 1, 0) %!error prctile (1, 1, 3)
--- a/scripts/statistics/base/probit.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/probit.m Fri Aug 12 14:16:34 2011 -0400 @@ -27,10 +27,18 @@ function y = probit (p) - if (nargin == 1) - y = stdnormal_inv (p); - else + + if (nargin != 1) print_usage (); endif + y = stdnormal_inv (p); + endfunction + +%!assert(probit([-1, 0, 0.5, 1, 2]), [NaN, -Inf, 0, Inf, NaN]); + +%% Test input validation +%!error probit () +%!error probit (1, 2) +
--- a/scripts/statistics/base/quantile.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/quantile.m Fri Aug 12 14:16:34 2011 -0400 @@ -103,18 +103,26 @@ ## Author: Ben Abbott <bpabbott@mac.com> ## Description: Matlab style quantile function of a discrete/continuous distribution -function q = quantile (x, p, dim = 1, method = 5) +function q = quantile (x, p = [], dim = 1, method = 5) if (nargin < 1 || nargin > 4) print_usage (); endif - if (nargin < 2) + if (! (isnumeric (x) || islogical (x))) + error ("quantile: X must be a numeric vector or matrix"); + endif + + if (isempty (p)) p = [0.00 0.25, 0.50, 0.75, 1.00]; endif - if (!(isscalar (dim) && dim == fix (dim)) || - !(1 <= dim && dim <= ndims (x))) + if (! (isnumeric (p) && isvector (p))) + error ("quantile: P must be a numeric vector"); + endif + + if (!(isscalar (dim) && dim == fix (dim)) + || !(1 <= dim && dim <= ndims (x))) error ("quantile: DIM must be an integer and a valid dimension"); endif @@ -143,6 +151,7 @@ endfunction + %!test %! p = 0.5; %! x = sort (rand (11)); @@ -282,9 +291,14 @@ %% Test input validation %!error quantile () %!error quantile (1, 2, 3, 4, 5) +%!error quantile (['A'; 'B'], 10) +%!error quantile (1:10, [true, false]) +%!error quantile (1:10, ones (2,2)) %!error quantile (1, 1, 1.5) %!error quantile (1, 1, 0) %!error quantile (1, 1, 3) +%!error quantile ((1:5)', 0.5, 1, 0) +%!error quantile ((1:5)', 0.5, 1, 10) ## For the cumulative probability values in @var{p}, compute the ## quantiles, @var{q} (the inverse of the cdf), for the sample, @var{x}. @@ -304,37 +318,35 @@ print_usage (); endif - if (!isnumeric (x)) - error ("quantile: X must be a numeric vector or matrix"); + if (isinteger (x) || islogical (x)) + x = double (x); endif - ## Save length and set shape of quantiles. - n = numel (p); + ## set shape of quantiles to column vector. p = p(:); ## Save length and set shape of samples. ## FIXME: does sort guarantee that NaN's come at the end? x = sort (x); m = sum (! isnan (x)); - mx = size (x, 1); - nx = size (x, 2); + [xr, xc] = size (x); ## Initialize output values. - inv = Inf*(-(p < 0) + (p > 1)); - inv = repmat (inv, 1, nx); + inv = Inf (class (x)) * (-(p < 0) + (p > 1)); + inv = repmat (inv, 1, xc); ## Do the work. - if (any(k = find((p >= 0) & (p <= 1)))) + if (any (k = find ((p >= 0) & (p <= 1)))) n = length (k); - p = p (k); - ## Special case. - if (mx == 1) + p = p(k); + ## Special case of 1 row. + if (xr == 1) inv(k,:) = repmat (x, n, 1); - return + return; endif ## The column-distribution indices. - pcd = kron (ones (n, 1), mx*(0:nx-1)); + pcd = kron (ones (n, 1), xr*(0:xc-1)); mm = kron (ones (n, 1), m); switch (method) case {1, 2, 3} @@ -375,7 +387,7 @@ p = kron (p, m-1) + 1; case 8 - ## Median unbiased . + ## Median unbiased. p = kron (p, m+1/3) + 1/3; case 9 @@ -387,7 +399,7 @@ endswitch ## Duplicate single values. - imm1 = mm == 1; + imm1 = (mm == 1); x(2,imm1) = x(1,imm1); ## Interval indices.
--- a/scripts/statistics/base/range.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/range.m Fri Aug 12 14:16:34 2011 -0400 @@ -37,20 +37,24 @@ function y = range (x, dim) + if (nargin < 1 || nargin > 2) + print_usage (); + endif + if (nargin == 1) y = max (x) - min (x); - elseif (nargin == 2) + else y = max (x, [], dim) - min (x, [], dim); - else - print_usage (); endif endfunction -%!assert(range (1:10), 9) -%!assert(range (magic (3)), [5, 8, 5]) -%!assert(range (magic (3), 2), [7; 4; 7]) -%!assert(range (2), 0) + +%!assert(range (1:10), 9); +%!assert(range (single(1:10)), single(9)); +%!assert(range (magic (3)), [5, 8, 5]); +%!assert(range (magic (3), 2), [7; 4; 7]); +%!assert(range (2), 0); %% Test input validation %!error range ()
--- a/scripts/statistics/base/ranks.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/ranks.m Fri Aug 12 14:16:34 2011 -0400 @@ -37,7 +37,7 @@ print_usage (); endif - if (!isnumeric(x)) + if (! (isnumeric (x) || islogical (x))) error ("ranks: X must be a numeric vector or matrix"); endif @@ -45,10 +45,7 @@ sz = size (x); if (nargin != 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -89,18 +86,18 @@ endfunction -%!assert(ranks (1:2:10), 1:5) -%!assert(ranks (10:-2:1), 5:-1:1) -%!assert(ranks ([2, 1, 2, 4]), [2.5, 1, 2.5, 4]) -%!assert(ranks (ones(1, 5)), 3*ones(1, 5)) -%!assert(ranks (1e6*ones(1, 5)), 3*ones(1, 5)) -%!assert(ranks (rand (1, 5), 1), ones(1, 5)) +%!assert(ranks (1:2:10), 1:5); +%!assert(ranks (10:-2:1), 5:-1:1); +%!assert(ranks ([2, 1, 2, 4]), [2.5, 1, 2.5, 4]); +%!assert(ranks (ones(1, 5)), 3*ones(1, 5)); +%!assert(ranks (1e6*ones(1, 5)), 3*ones(1, 5)); +%!assert(ranks (rand (1, 5), 1), ones(1, 5)); %% Test input validation %!error ranks () %!error ranks (1, 2, 3) %!error ranks ({1, 2}) -%!error ranks (true(2,1)) +%!error ranks (['A'; 'B']) %!error ranks (1, 1.5) %!error ranks (1, 0) %!error ranks (1, 3)
--- a/scripts/statistics/base/run_count.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/run_count.m Fri Aug 12 14:16:34 2011 -0400 @@ -36,7 +36,7 @@ print_usage (); endif - if (!isnumeric(x)) + if (! (isnumeric (x) || islogical (x))) error ("run_count: X must be a numeric vector or matrix"); endif @@ -48,10 +48,7 @@ sz = size (x); if (nargin != 3) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == fix (dim)) || !(1 <= dim && dim <= nd)) @@ -59,6 +56,7 @@ endif endif + ## Algorithm works on rows. Permute array if necessary, ipermute back at end if (dim != 1) perm = [1 : nd]; perm(1) = dim; @@ -76,7 +74,7 @@ infvec = Inf ([1, sz(2 : end)]); ind = find (diff ([infvec; x; -infvec]) < 0); - tmp(ind(2:end) - 1) = diff(ind); + tmp(ind(2:end) - 1) = diff (ind); tmp = tmp(idx{:}); sz(1) = n; @@ -86,7 +84,7 @@ retval(idx{:}) = sum (tmp == k); endfor idx{1} = n; - retval (idx{:}) = sum (tmp >= n); + retval(idx{:}) = sum (tmp >= n); if (dim != 1) retval = ipermute (retval, perm); @@ -105,7 +103,7 @@ %!error run_count (1) %!error run_count (1, 2, 3, 4) %!error run_count ({1, 2}, 3) -%!error run_count (true(3), 3) +%!error run_count (['A'; 'A'; 'B'], 3) %!error run_count (1:5, ones(2,2)) %!error run_count (1:5, 1.5) %!error run_count (1:5, -2)
--- a/scripts/statistics/base/runlength.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/runlength.m Fri Aug 12 14:16:34 2011 -0400 @@ -30,11 +30,12 @@ ## @end deftypefn function [count, value] = runlength (x) + if (nargin != 1) print_usage (); endif - if (!isnumeric (x) || !isvector (x)) + if (!(isnumeric (x) || islogical (x)) || !isvector (x)) error ("runlength: X must be a numeric vector"); endif @@ -47,8 +48,10 @@ if (nargout == 2) value = x(idx); endif + endfunction + %!assert (runlength([2 2 0 4 4 4 0 1 1 1 1]), [2 1 3 1 4]); %!assert (runlength([2 2 0 4 4 4 0 1 1 1 1]'), [2 1 3 1 4]); %!test @@ -59,5 +62,5 @@ %% Test input validation %!error runlength () %!error runlength (1, 2) -%!error runlength (true(1,2)) +%!error runlength (['A'; 'B']) %!error runlength (ones(2,2))
--- a/scripts/statistics/base/skewness.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/skewness.m Fri Aug 12 14:16:34 2011 -0400 @@ -51,7 +51,7 @@ print_usage (); endif - if (!isnumeric(x)) + if (! (isnumeric (x) || islogical (x))) error ("skewness: X must be a numeric vector or matrix"); endif @@ -59,10 +59,7 @@ sz = size (x); if (nargin != 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == round (dim)) || !(1 <= dim && dim <= nd)) @@ -70,19 +67,18 @@ endif endif - c = sz(dim); - idx = ones (1, nd); - idx(dim) = c; - x = x - repmat (mean (x, dim), idx); + n = sz(dim); sz(dim) = 1; + x = center (x, dim); # center also promotes integer to double for next line retval = zeros (sz, class (x)); s = std (x, [], dim); - ind = find (s > 0); + idx = find (s > 0); x = sum (x .^ 3, dim); - retval(ind) = x(ind) ./ (c * s(ind) .^ 3); + retval(idx) = x(idx) ./ (n * s(idx) .^ 3); endfunction + %!assert(skewness ([-1,0,1]), 0); %!assert(skewness ([-2,0,1]) < 0); %!assert(skewness ([-1,0,2]) > 0); @@ -92,10 +88,12 @@ %! y = [x, 2*x]; %! assert(all (abs (skewness (y) - [0.75, 0.75]) < sqrt (eps))); +%!assert (skewness (single(1)), single(0)); + %% Test input validation %!error skewness () %!error skewness (1, 2, 3) -%!error skewness ([true true]) +%!error skewness (['A'; 'B']) %!error skewness (1, ones(2,2)) %!error skewness (1, 1.5) %!error skewness (1, 0)
--- a/scripts/statistics/base/spearman.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/spearman.m Fri Aug 12 14:16:34 2011 -0400 @@ -39,11 +39,12 @@ function rho = spearman (x, y = []) - if ((nargin < 1) || (nargin > 2)) + if (nargin < 1 || nargin > 2) print_usage (); endif - if (! (isnumeric (x) && isnumeric (y))) + if ( ! (isnumeric (x) || islogical (x)) + || ! (isnumeric (y) || islogical (y))) error ("spearman: X and Y must be numeric matrices or vectors"); endif @@ -51,30 +52,43 @@ error ("spearman: X and Y must be 2-D matrices or vectors"); endif - if (rows (x) == 1) - x = x'; + if (isrow (x)) + x = x.'; endif - n = rows (x); if (nargin == 1) - rho = corrcoef (ranks (x)); + rho = corr (ranks (x)); else - if (rows (y) == 1) - y = y'; + if (isrow (y)) + y = y.'; endif - if (rows (y) != n) + if (rows (x) != rows (y)) error ("spearman: X and Y must have the same number of observations"); endif - rho = corrcoef (ranks (x), ranks (y)); + rho = corr (ranks (x), ranks (y)); + endif + + ## Restore class cleared by ranks + if (isa (x, 'single') || isa (y, 'single')) + rho = single (rho); endif endfunction + +%!test +%! x = 1:10; +%! y = exp (x); +%! assert (spearman (x,y), 1, 5*eps); +%! assert (spearman (x,-y), -1, 5*eps); + +%!assert(spearman ([1 2 3], [-1 1 -2]), -0.5, 5*eps) + %% Test input validation %!error spearman (); %!error spearman (1, 2, 3); -%!error spearman ([true, true]); -%!error spearman (ones(1,2), [true, true]); +%!error spearman (['A'; 'B']); +%!error spearman (ones(1,2), {1, 2}); %!error spearman (ones (2,2,2)); %!error spearman (ones (2,2), ones (2,2,2)); %!error spearman (ones (2,2), ones (3,2));
--- a/scripts/statistics/base/statistics.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/statistics.m Fri Aug 12 14:16:34 2011 -0400 @@ -38,7 +38,7 @@ print_usage (); endif - if (!isnumeric(x)) + if (! (isnumeric (x) || islogical (x))) error ("statistics: X must be a numeric vector or matrix"); endif @@ -46,10 +46,7 @@ sz = size (x); if (nargin != 2) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif + (dim = find (sz > 1, 1)) || (dim = 1); else if (!(isscalar (dim) && dim == round (dim)) || !(1 <= dim && dim <= nd)) @@ -68,16 +65,22 @@ endfunction + %!test -%! x = rand(7,5); +%! x = rand (7,5); %! s = statistics (x); -%! m = median (x); -%! assert (m, s(3,:), eps); +%! assert (min (x), s(1,:), eps); +%! assert (median (x), s(3,:), eps); +%! assert (max (x), s(5,:), eps); +%! assert (mean (x), s(6,:), eps); +%! assert (std (x), s(7,:), eps); +%! assert (skewness (x), s(8,:), eps); +%! assert (kurtosis (x), s(9,:), eps); %% Test input validation %!error statistics () %!error statistics (1, 2, 3) -%!error statistics ([true true]) +%!error statistics (['A'; 'B']) %!error statistics (1, ones(2,2)) %!error statistics (1, 1.5) %!error statistics (1, 0)
--- a/scripts/statistics/base/std.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/std.m Fri Aug 12 14:16:34 2011 -0400 @@ -67,7 +67,7 @@ print_usage (); endif - if (! (isnumeric (x))) + if (! (isnumeric (x) || islogical (x))) error ("std: X must be a numeric vector or matrix"); endif @@ -78,22 +78,27 @@ error ("std: normalization OPT must be 0 or 1"); endif + nd = ndims (x); sz = size (x); if (nargin < 3) ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; + (dim = find (sz > 1, 1)) || (dim = 1); + else + if (!(isscalar (dim) && dim == fix (dim)) + || !(1 <= dim && dim <= nd)) + error ("std: DIM must be an integer and a valid dimension"); endif endif - n = size (x, dim); - if (n == 1) - retval = zeros (sz); - elseif (numel (x) > 0) + n = sz(dim); + if (n == 1 || isempty (x)) + if (isa (x, 'single')) + retval = zeros (sz, 'single'); + else + retval = zeros (sz); + endif + else retval = sqrt (sumsq (center (x, dim), dim) / (n - 1 + opt)); - else - error ("std: X must not be empty"); endif endfunction @@ -102,14 +107,21 @@ %!test %! x = ones (10, 2); %! y = [1, 3]; -%! assert(std (x) == [0, 0] && abs (std (y) - sqrt (2)) < sqrt (eps)); -%! assert (std (x, 0, 3), zeros (10, 2)) -%! assert (std (ones (3, 1, 2), 0, 2), zeros (3, 1, 2)) +%! assert(std (x) == [0, 0]); +%! assert(std (y), sqrt (2), sqrt (eps)); +%! assert(std (x, 0, 2), zeros (10, 1)); + +%!assert(std (ones (3, 1, 2), 0, 2), zeros (3, 1, 2)); +%!assert(std ([1 2], 0), sqrt(2)/2, 5*eps); +%!assert(std ([1 2], 1), 0.5, 5*eps); +%!assert(std(1), 0); +%!assert(std(single(1)), single(0)); +%!assert(std([]), []); +%!assert(std(ones (1,3,0,2)), ones (1,3,0,2)); %% Test input validation %!error std (); %!error std (1, 2, 3, 4); -%!error std (true(1,2)) +%!error std (['A'; 'B']) %!error std (1, -1); -%!error std ([], 1);
--- a/scripts/statistics/base/studentize.m Fri Aug 12 14:05:48 2011 -0400 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -## Copyright (C) 1995-2011 Kurt Hornik -## -## This file is part of Octave. -## -## Octave is free software; you can redistribute it and/or modify it -## under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 3 of the License, or (at -## your option) any later version. -## -## Octave is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with Octave; see the file COPYING. If not, see -## <http://www.gnu.org/licenses/>. - -## -*- texinfo -*- -## @deftypefn {Function File} {} studentize (@var{x}) -## @deftypefnx {Function File} {} studentize (@var{x}, @var{dim}) -## If @var{x} is a vector, subtract its mean and divide by its standard -## deviation. -## -## If @var{x} is a matrix, do the above along the first non-singleton -## dimension. -## If the optional argument @var{dim} is given, operate along this dimension. -## @seealso{center} -## @end deftypefn - -## Author: KH <Kurt.Hornik@wu-wien.ac.at> -## Description: Subtract mean and divide by standard deviation - -function t = studentize (x, dim) - - if (nargin != 1 && nargin != 2) - print_usage (); - endif - - if (! isnumeric(x)) - error ("studentize: X must be a numeric vector or matrix"); - endif - - if (isinteger (x)) - x = double (x); - endif - - nd = ndims (x); - sz = size (x); - if (nargin != 2) - ## Find the first non-singleton dimension. - dim = find (sz > 1, 1); - if (isempty (dim)) - dim = 1; - endif - else - if (!(isscalar (dim) && dim == fix (dim)) - || !(1 <= dim && dim <= nd)) - error ("studentize: DIM must be an integer and a valid dimension"); - endif - endif - - c = sz(dim); - if (c == 0) - t = x; - else - idx = ones (1, nd); - idx(dim) = c; - t = x - repmat (mean (x, dim), idx); - t = t ./ repmat (max (cat (dim, std(t, [], dim), ! any (t, dim)), [], dim), idx); - endif - -endfunction - -%!assert(studentize ([1,2,3]), [-1,0,1]) -%!assert(studentize (int8 ([1,2,3])), [-1,0,1]) -#%!assert(studentize (ones (3,2,0,2)), zeros (3,2,0,2)) -%!assert(studentize ([2,0,-2;0,2,0;-2,-2,2]), [1,0,-1;0,1,0;-1,-1,1]) - -%% Test input validation -%!error studentize () -%!error studentize (1, 2, 3) -%!error studentize ([true true]) -%!error studentize (1, ones(2,2)) -%!error studentize (1, 1.5) -%!error studentize (1, 0) -%!error studentize (1, 3) -
--- a/scripts/statistics/base/table.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/table.m Fri Aug 12 14:16:34 2011 -0400 @@ -60,6 +60,7 @@ endfunction + %% Test input validation %!error table () %!error table (1, 2, 3)
--- a/scripts/statistics/base/var.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/base/var.m Fri Aug 12 14:16:34 2011 -0400 @@ -64,7 +64,7 @@ print_usage (); endif - if (!isnumeric (x)) + if (! (isnumeric (x) || islogical (x))) error ("var: X must be a numeric vector or matrix"); endif @@ -75,16 +75,25 @@ error ("var: normalization OPT must be 0 or 1"); endif + nd = ndims (x); + sz = size (x); if (nargin < 3) - dim = find (size (x) > 1, 1); - if (isempty (dim)) - dim = 1; + ## Find the first non-singleton dimension. + (dim = find (sz > 1, 1)) || (dim = 1); + else + if (!(isscalar (dim) && dim == fix (dim)) + || !(1 <= dim && dim <= nd)) + error ("var: DIM must be an integer and a valid dimension"); endif endif - n = size (x, dim); + n = sz(dim); if (n == 1) - retval = zeros (size (x), class (x)); + if (isa (x, 'single')) + retval = zeros (sz, 'single'); + else + retval = zeros (sz); + endif elseif (numel (x) > 0) retval = sumsq (center (x, dim), dim) / (n - 1 + opt); else @@ -93,15 +102,17 @@ endfunction -%!assert (var (13), 0) -%!assert (var ([1,2,3]), 1) -%!assert (var ([1,2,3], 1), 2/3, eps) -%!assert (var ([1,2,3], [], 1), [0,0,0]) + +%!assert(var (13), 0); +%!assert(var (single(13)), single(0)); +%!assert(var ([1,2,3]), 1); +%!assert(var ([1,2,3], 1), 2/3, eps); +%!assert(var ([1,2,3], [], 1), [0,0,0]); %% Test input validation %!error var () %!error var (1,2,3,4) -%!error var (true(1,2)) +%!error var (['A'; 'B']) %!error var (1, -1); %!error var ([],1)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scripts/statistics/base/zscore.m Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,84 @@ +## Copyright (C) 1995-2011 Kurt Hornik +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## <http://www.gnu.org/licenses/>. + +## -*- texinfo -*- +## @deftypefn {Function File} {} zscore (@var{x}) +## @deftypefnx {Function File} {} zscore (@var{x}, @var{dim}) +## If @var{x} is a vector, subtract its mean and divide by its standard +## deviation. +## +## If @var{x} is a matrix, do the above along the first non-singleton +## dimension. +## If the optional argument @var{dim} is given, operate along this dimension. +## @seealso{center} +## @end deftypefn + +## Author: KH <Kurt.Hornik@wu-wien.ac.at> +## Description: Subtract mean and divide by standard deviation + +function z = zscore (x, dim) + + if (nargin != 1 && nargin != 2) + print_usage (); + endif + + if (! (isnumeric (x) || islogical (x))) + error ("zscore: X must be a numeric vector or matrix"); + endif + + nd = ndims (x); + sz = size (x); + if (nargin != 2) + ## Find the first non-singleton dimension. + (dim = find (sz > 1, 1)) || (dim = 1); + else + if (!(isscalar (dim) && dim == fix (dim)) + || !(1 <= dim && dim <= nd)) + error ("zscore: DIM must be an integer and a valid dimension"); + endif + endif + + n = sz(dim); + if (n == 0) + z = x; + else + x = center (x, dim); # center also promotes integer to double for next line + z = zeros (sz, class (x)); + s = std (x, [], dim); + s(s==0) = 1; + z = bsxfun (@rdivide, x, s); + endif + +endfunction + + +%!assert(zscore ([1,2,3]), [-1,0,1]) +%!assert(zscore (single([1,2,3])), single([-1,0,1])) +%!assert(zscore (int8([1,2,3])), [-1,0,1]) +%!assert(zscore (ones (3,2,2,2)), zeros (3,2,2,2)) +%!assert(zscore ([2,0,-2;0,2,0;-2,-2,2]), [1,0,-1;0,1,0;-1,-1,1]) + +%% Test input validation +%!error zscore () +%!error zscore (1, 2, 3) +%!error zscore (['A'; 'B']) +%!error zscore (1, ones(2,2)) +%!error zscore (1, 1.5) +%!error zscore (1, 0) +%!error zscore (1, 3) +
--- a/scripts/statistics/distributions/logistic_inv.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/distributions/logistic_inv.m Fri Aug 12 14:16:34 2011 -0400 @@ -31,7 +31,11 @@ print_usage (); endif - inv = zeros (size (x)); + if (isa (x, 'single')) + inv = zeros (size (x), 'single'); + else + inv = zeros (size (x)); + endif k = find ((x < 0) | (x > 1) | isnan (x)); if (any (k))
--- a/scripts/statistics/tests/cor_test.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/statistics/tests/cor_test.m Fri Aug 12 14:16:34 2011 -0400 @@ -91,7 +91,7 @@ m = method (1); if (m == "p") - r = cor (x, y); + r = corr (x, y); df = n - 2; t.method = "Pearson's product moment correlation"; t.params = df;
--- a/scripts/strings/deblank.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/deblank.m Fri Aug 12 14:16:34 2011 -0400 @@ -18,7 +18,7 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} deblank (@var{s}) -## Remove trailing blanks and nulls from @var{s}. If @var{s} +## Remove trailing whitespace and nulls from @var{s}. If @var{s} ## is a matrix, @var{deblank} trims each row to the length of longest ## string. If @var{s} is a cell array, operate recursively on each ## element of the cell array. @@ -33,53 +33,33 @@ print_usage (); endif - char_arg = ischar (s); - - if (char_arg || isnumeric (s)) + if (ischar (s)) - if (! isempty (s)) - if (char_arg) - k = find (! isspace (s) & s != "\0"); - else - warning ("deblank: expecting character string argument"); - k = find (s != 0); - endif - - if (isempty (k)) - s = resize (s, 0, 0); - else - s = s(:,1:ceil (max (k) / rows (s))); - endif + k = find (! isspace (s) & s != "\0"); + if (isempty (s) || isempty (k)) + s = ""; + else + s = s(:,1:ceil (max (k) / rows (s))); endif - elseif (iscell(s)) + elseif (iscell (s)) - s = cellfun (@deblank, s, "uniformoutput", false); + s = regexprep (s, "[\\s\v\\0]+$", ''); else - error ("deblank: expecting character string argument"); + error ("deblank: S argument must be a string or cellstring"); endif endfunction -%!assert (strcmp (deblank (" f o o "), " f o o")); -%!assert (deblank ([]), []) -%!assert (deblank ({}), {}) -%!assert (deblank (""), "") - -%!assert (deblank ([0,0,0]), []) +%!assert (strcmp (deblank (" f o o \0"), " f o o")); %!assert (deblank (' '), '') %!assert (deblank (" "), "") - -%!assert (typeinfo (deblank (" ")), "string") -%!assert (typeinfo (deblank (' ')), "sq_string") +%!assert (deblank (""), "") +%!assert (deblank ({}), {}) -%!assert (deblank ([1,2,0]), [1,2]) -%!assert (deblank ([1,2,0,32]), [1,2,0,32]) +%!error <Invalid call to deblank> deblank (); +%!error <Invalid call to deblank> deblank ("foo", "bar"); +%!error <argument must be a string> deblank (1); -%!assert (deblank (int8 ([1,2,0])), int8 ([1,2])) - -%!error deblank (); - -%!error deblank ("foo", "bar");
--- a/scripts/strings/index.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/index.m Fri Aug 12 14:16:34 2011 -0400 @@ -62,13 +62,13 @@ if (strcmp (direction, "last")) if (iscell (f)) - n = cellfun (@min, f); + n = cellfun ("min", f); else n = f(end); endif elseif (strcmp (direction, "first")) if (iscell (f)) - n = cellfun (@max, f); + n = cellfun ("max", f); else n = f(1); endif
--- a/scripts/strings/mat2str.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/mat2str.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,7 +28,7 @@ ## scalar then both real and imaginary parts of the matrix are printed ## to the same precision. Otherwise @code{@var{n} (1)} defines the ## precision of the real part and @code{@var{n} (2)} defines the -## precision of the imaginary part. The default for @var{n} is 17. +## precision of the imaginary part. The default for @var{n} is 15. ## ## If the argument 'class' is given, then the class of @var{x} is ## included in the string in such a way that the eval will result in the @@ -56,13 +56,13 @@ if (nargin < 2 || isempty (n)) ## Default precision - n = 17; + n = 15; endif if (nargin < 3) if (ischar (n)) cls = n; - n = 17; + n = 15; else cls = ""; endif @@ -137,3 +137,4 @@ %!assert (mat2str (true), "true"); %!assert (mat2str (false), "false"); %!assert (mat2str (logical (eye (2))), "[true,false;false,true]"); +%!assert (mat2str (0.7), "0.7")
--- a/scripts/strings/strcat.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/strcat.m Fri Aug 12 14:16:34 2011 -0400 @@ -61,14 +61,14 @@ elseif (nargin > 1) ## Convert to cells of strings uo = "uniformoutput"; - reals = cellfun (@isreal, varargin); + reals = cellfun ("isreal", varargin); if (any (reals)) - varargin(reals) = cellfun (@char, varargin(reals), uo, false); + varargin(reals) = cellfun ("char", varargin(reals), uo, false); endif - chars = cellfun (@ischar, varargin); + chars = cellfun ("isclass", varargin, "char"); allchar = all (chars); - varargin(chars) = cellfun (@cellstr, varargin(chars), uo, false); - if (! all (cellfun (@iscell, varargin))) + varargin(chars) = cellfun ("cellstr", varargin(chars), uo, false); + if (! all (cellfun ("isclass", varargin, "cell"))) error ("strcat: inputs must be strings or cells of strings"); endif @@ -81,7 +81,7 @@ endif ## Cellfun handles everything for us. - st = cellfun (@horzcat, varargin{:}, uo, false); + st = cellfun ("horzcat", varargin{:}, uo, false); if (allchar) ## If all inputs were strings, return strings.
--- a/scripts/strings/strmatch.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/strmatch.m Fri Aug 12 14:16:34 2011 -0400 @@ -19,13 +19,15 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Function File} {} strmatch (@var{s}, @var{A}, "exact") -## Return indices of entries of @var{A} that match the string @var{s}. -## The second argument @var{A} may be a string matrix or a cell array of -## strings. If the third argument @code{"exact"} is not given, then +## @deftypefn {Function File} {} strmatch (@var{s}, @var{A}) +## @deftypefnx {Function File} {} strmatch (@var{s}, @var{A}, "exact") +## Return indices of entries of @var{A} which begin with the string @var{s}. +## The second argument @var{A} must be a string, character matrix, or a cell +## array of strings. If the third argument @code{"exact"} is not given, then ## @var{s} only needs to match @var{A} up to the length of @var{s}. -## Trailing whitespace is ignored. -## Results are returned as a column vector. +## Trailing spaces and nulls in @var{s} and @var{A} are ignored when matching. +## option. +## ## For example: ## ## @example @@ -33,13 +35,16 @@ ## strmatch ("apple", "apple juice") ## @result{} 1 ## -## strmatch ("apple", ["apple pie"; "apple juice"; "an apple"]) +## strmatch ("apple", ["apple "; "apple juice"; "an apple"]) ## @result{} [1; 2] ## -## strmatch ("apple", @{"apple pie"; "apple juice"; "tomato"@}) -## @result{} [1; 2] +## strmatch ("apple", ["apple "; "apple juice"; "an apple"], "exact") +## @result{} [1] ## @end group ## @end example +## +## @strong{Note:} @code{strmatch} is scheduled for deprecation. Use +## @code{strcmpi} or @code{strncmpi} in all new code. ## @seealso{strfind, findstr, strcmp, strncmp, strcmpi, strncmpi, find} ## @end deftypefn @@ -52,29 +57,19 @@ print_usage (); endif - if (! ischar (s)) + if (! ischar (s) || (! isempty (s) && ! isvector (s))) error ("strmatch: S must be a string"); + elseif (! (ischar (A) || iscellstr (A))) + error ("strmatch: A must be a string or cell array of strings"); endif - ## Truncate trailing whitespace. - s = strtrimr (s); - + ## Trim blanks and nulls from search string + s = regexprep (s, "[ \\0]+$", ''); len = length (s); exact = nargin == 3 && ischar (exact) && strcmp (exact, "exact"); - if (iscell (A)) - if (len > 0) - idx = find (strncmp (s, A, len)); - else - idx = find (strcmp (s, A)); - endif - if (exact) - ## We can't just use strcmp, because we need to ignore whitespace. - B = cellfun (@strtrimr, A(idx), "uniformoutput", false); - idx = idx (strcmp (s, B)); - endif - elseif (ischar (A)) + if (ischar (A)) [nr, nc] = size (A); if (len > nc) idx = []; @@ -82,34 +77,43 @@ match = all (bsxfun (@eq, A(:,1:len), s), 2); if (exact) AA = A(:,len+1:nc); - match &= all (AA == "\0" | AA == " ", 2); + match &= all (AA == " " | AA == "\0", 2); endif idx = find (match); endif else - error ("strmatch: A must be a string or cell array of strings"); + if (len > 0) + idx = find (strncmp (s, A, len)); + else + idx = find (strcmp (s, A)); + endif + if (exact) + ## We can't just use strcmp, because we need to ignore spaces at end. + B = regexprep (A(idx), "[ \\0]+$", ''); + idx = idx(strcmp (s, B)); + endif endif endfunction -## Removes nuls and blanks from the end of the array -function s = strtrimr (s) - blnks = s == "\0" | s == " "; - i = find (blnks, 1, "last"); - if (i && all (blnks(i:end))) - s = s(1:i-1); - endif -endfunction -%!error <Invalid call to strmatch> strmatch(); -%!error <Invalid call to strmatch> strmatch("a", "aaa", "exact", 1); %!assert (strmatch("a", {"aaa", "bab", "bbb"}), 1); %!assert (strmatch ("apple", "apple juice"), 1); -%!assert (strmatch ("apple", ["apple pie"; "apple juice"; "an apple"]), -%! [1; 2]); -%!assert (strmatch ("apple", {"apple pie"; "apple juice"; "tomato"}), -%! [1; 2]); +%!assert (strmatch ("apple", ["apple pie"; "apple juice"; "an apple"]), [1; 2]); +%!assert (strmatch ("apple", {"apple pie"; "apple juice"; "tomato"}), [1; 2]); %!assert (strmatch ("apple pie", "apple"), []); -%!assert (strmatch ("a b", {"a b", "a c", "c d"})); -%!assert (strmatch ("", {"", "foo", "bar", ""}), [1, 4]) -%!assert (strmatch ('', { '', '% comment line', 'var a = 5', ''}, 'exact'), [1,4]) +%!assert (strmatch ("a ", "a"), 1); +%!assert (strmatch ("a", "a \0", "exact"), 1); +%!assert (strmatch ("a b", {"a b", "a c", "c d"}), 1); +%!assert (strmatch ("", {"", "foo", "bar", ""}), [1, 4]); +%!assert (strmatch ('', { '', '% comment', 'var a = 5', ''}, 'exact'), [1,4]); + +%% Test input validation +%!error <Invalid call to strmatch> strmatch(); +%!error <Invalid call to strmatch> strmatch("a"); +%!error <Invalid call to strmatch> strmatch("a", "aaa", "exact", 1); +%!error <S must be a string> strmatch(1, "aaa"); +%!error <S must be a string> strmatch(char ("a", "bb"), "aaa"); +%!error <A must be a string> strmatch("a", 1); +%!error <A must be a string> strmatch("a", {"hello", [1]}); +
--- a/scripts/strings/strsplit.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/strsplit.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,7 +28,7 @@ function s = strsplit (p, sep, strip_empty = false) if (nargin < 2 || nargin > 3 || ! ischar (p) || rows (p) > 1 - || ! ischar (sep) || ! islogical (strip_empty)) + || ! ischar (sep) || ! isscalar (strip_empty)) print_usage (); endif
--- a/scripts/strings/strtrim.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/strtrim.m Fri Aug 12 14:16:34 2011 -0400 @@ -18,7 +18,7 @@ ## -*- texinfo -*- ## @deftypefn {Function File} {} strtrim (@var{s}) -## Remove leading and trailing whitespace and nulls from @var{s}. If +## Remove leading and trailing whitespace from @var{s}. If ## @var{s} is a matrix, @var{strtrim} trims each row to the length of ## longest string. If @var{s} is a cell array, operate recursively on ## each element of the cell array. For example: @@ -46,19 +46,19 @@ if (ischar (s)) - k = find (! isspace (s) & s != "\0"); + k = find (! isspace (s)); if (isempty (s) || isempty (k)) s = ""; else s = s(:, ceil (min (k) / rows (s)):ceil (max (k) / rows (s))); endif - elseif (iscell(s)) + elseif (iscell (s)) - s = regexprep (s, "^[\\s\v\\0]+|[\\s\v\\0]+$", ''); + s = regexprep (s, "^[\\s\v]+|[\\s\v]+$", ''); else - error ("strtrim: S argument must be a string"); + error ("strtrim: S argument must be a string or cellstring"); endif endfunction
--- a/scripts/strings/untabify.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/untabify.m Fri Aug 12 14:16:34 2011 -0400 @@ -52,64 +52,72 @@ function s = untabify (t, tw = 8, dblank = false) - if (nargin > 0 && nargin < 4 && (ischar (t) || iscellstr (t))) - if (ischar (t)) - s = replace_tabs (t, tw); - else - s = cellfun (@(str) replace_tabs (str, tw), t, "uniformoutput", false); - endif - if (dblank) - s = deblank (s); - endif - else - print_usage (); - endif + if (nargin < 1 || nargin > 3) + print_usage (); + elseif (! (ischar (t) || iscellstr (t))) + error ("untabify: T must be a string or cellstring"); + endif + + if (ischar (t)) + s = replace_tabs (t, tw); + else + s = cellfun (@(str) replace_tabs (str, tw), t, "uniformoutput", false); + endif + + if (dblank) + s = deblank (s); + endif endfunction function s = replace_tabs (t, tw) - if (ndims (t) == 2) - if (isempty (t)) - s = t; - else - nr = rows (t); - sc = cell (nr, 1); - for j = 1:nr - n = 1:numel(t(j,:)); - m = find (t(j,:) == "\t"); - t(j,m) = " "; - for i = 1:numel(m) - k = tw * ceil (n(m(i)) / tw); - dn = k - n(m(i)); - n(m(i):end) += dn; - endfor - sc{j} = blanks (n(end)); - sc{j}(n) = t(j,:); - endfor - s = char (sc); - endif - else - error ("untabify: character strings to untabify must have 2 dimensions"); - endif + + if (ndims (t) != 2) + error ("untabify: character strings to untabify must have 2 dimensions"); + endif + + if (isempty (t)) + s = t; + else + nr = rows (t); + sc = cell (nr, 1); + for j = 1:nr + n = 1:numel(t(j,:)); + m = find (t(j,:) == "\t"); + t(j,m) = " "; + for i = 1:numel(m) + k = tw * ceil (n(m(i)) / tw); + dn = k - n(m(i)); + n(m(i):end) += dn; + endfor + sc{j} = blanks (n(end)); + sc{j}(n) = t(j,:); + endfor + s = char (sc); + endif + endfunction + %!test %! s = untabify ("\thello\t"); -%! assert (isequal (s, horzcat (blanks(8), "hello "))) +%! assert (s, [blanks(8) "hello" blanks(3)]); + +%!test +%! s = untabify ("\thello\t", 2); +%! assert (s, [blanks(2) "hello" blanks(1)]); %!test %! s = untabify ("\thello\t", 4, true); -%! assert (isequal (s, horzcat (blanks(4), "hello"))) +%! assert (s, [blanks(4) "hello"]); -%!test -%! s = untabify ("\thello\t", 2, true); -%! assert (isequal (s, horzcat (blanks(2), "hello"))) +%!assert (isempty (untabify (""))) %!test -%! s = untabify (""); -%! assert (isempty (s)) +%! s = char (randi ([97 97+25], 3, 3)); +%! assert (untabify (s), char (untabify (cellstr (s)))); -%!test -%! s = char (fix (100 + 10*rand (3,3))); -%! assert (isequal (untabify (s), untabify ({s}){1})) +%!error untabify () +%!error untabify (1,2,3,4) +%!error <must be a string> untabify (1)
--- a/scripts/strings/validatestring.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/strings/validatestring.m Fri Aug 12 14:16:34 2011 -0400 @@ -118,7 +118,7 @@ ## are the matches a substring of each other, if so, choose the ## shortest. If not, raise an error. match_idx = find (matches); - match_l = cellfun (@length, strarray(match_idx)); + match_l = cellfun ("length", strarray(match_idx)); longest_idx = find (match_l == max (match_l), 1); shortest_idx = find (match_l == min (match_l), 1); longest = strarray(match_idx)(longest_idx);
--- a/scripts/testfun/demo.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/testfun/demo.m Fri Aug 12 14:16:34 2011 -0400 @@ -17,35 +17,39 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Command} {} demo @var{name} @var{n} +## @deftypefn {Command} {} demo @var{name} +## @deftypefnx {Command} {} demo @var{name} @var{n} +## @deftypefnx {Function File} {} demo ('@var{name}') ## @deftypefnx {Function File} {} demo ('@var{name}', @var{n}) ## -## Runs any examples associated with the function '@var{name}'. +## Run example code block @var{n} associated with the function @var{name}. +## If @var{n} is not specified, all examples are run. +## ## Examples are stored in the script file, or in a file with the same -## name but no extension somewhere on your path. To keep them separate -## from the usual script code, all lines are prefixed by @code{%!}. Each -## example is introduced by the keyword 'demo' flush left to the prefix, -## with no intervening spaces. The remainder of the example can contain -## arbitrary Octave code. For example: +## name but no extension located on Octave's load path. To keep examples +## separate from regular script code, all lines are prefixed by @code{%!}. Each +## example must also be introduced by the keyword 'demo' flush left to the +## prefix with no intervening spaces. The remainder of the example can +## contain arbitrary Octave code. For example: ## ## @example ## @group -## %!demo -## %! t=0:0.01:2*pi; x = sin(t); -## %! plot(t,x) -## %! %------------------------------------------------- -## %! % the figure window shows one cycle of a sine wave +## %!demo +## %! t=0:0.01:2*pi; x = sin(t); +## %! plot (t,x) +## %! %------------------------------------------------- +## %! % the figure window shows one cycle of a sine wave ## @end group ## @end example ## ## Note that the code is displayed before it is executed, so a simple -## comment at the end suffices. It is generally not necessary to use -## disp or printf within the demo. +## comment at the end suffices for labeling what is being shown. It is +## generally not necessary to use @code{disp} or @code{printf} within the demo. ## ## Demos are run in a function environment with no access to external -## variables. This means that all demos in your function must use -## separate initialization code. Alternatively, you can combine your -## demos into one huge demo, with the code: +## variables. This means that every demo must have separate initialization +## code. Alternatively, all demos can be combined into a single large demo +## with the code ## ## @example ## %! input("Press <enter> to continue: ","s"); @@ -53,11 +57,13 @@ ## ## @noindent ## between the sections, but this is discouraged. Other techniques -## include using multiple plots by saying figure between each, or -## using subplot to put multiple plots in the same window. +## to avoid multiple initialization blocks include using multiple plots +## with a new @code{figure} command between each plot, or using @code{subplot} +## to put multiple plots in the same window. ## -## Also, since demo evaluates inside a function context, you cannot -## define new functions inside a demo. Instead you will have to +## Also, because demo evaluates within a function context, you cannot +## define new functions inside a demo. If you must have function blocks, +## rather than just anonymous functions or inline functions, you will have to ## use @code{eval(example('function',n))} to see them. Because eval only ## evaluates one line, or one statement if the statement crosses ## multiple lines, you must wrap your demo in "if 1 <demo stuff> endif" @@ -73,6 +79,7 @@ ## %! endif ## @end group ## @end example +## ## @seealso{test, example} ## @end deftypefn @@ -88,20 +95,19 @@ if (nargin < 2) n = 0; - elseif (strcmp ("char", class (n))) + elseif (ischar (n)) n = str2double (n); endif [code, idx] = test (name, "grabdemo"); - if (length (idx) == 0) - warning ("demo not available for %s", name); + if (isempty (idx)) + warning ("no demo available for %s", name); return; elseif (n >= length (idx)) warning ("only %d demos available for %s", length (idx) - 1, name); return; endif - if (n > 0) doidx = n; else @@ -123,7 +129,7 @@ __demo__; catch ## Let the programmer know which demo failed. - printf ("%s example %d: failed\n%s\n", name, doidx(i), __error_text__); + printf ("%s example %d: failed\n%s\n", name, doidx(i), lasterr ()); end_try_catch clear __demo__; endfor @@ -132,6 +138,6 @@ %!demo %! t=0:0.01:2*pi; x = sin(t); -%! plot(t,x) +%! plot (t,x) %! %------------------------------------------------- %! % the figure window shows one cycle of a sine wave
--- a/scripts/testfun/example.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/testfun/example.m Fri Aug 12 14:16:34 2011 -0400 @@ -17,16 +17,18 @@ ## <http://www.gnu.org/licenses/>. ## -*- texinfo -*- -## @deftypefn {Command} {} example @var{name} @var{n} +## @deftypefn {Command} {} example @var{name} +## @deftypefnx {Command} {} example @var{name} @var{n} +## @deftypefnx {Function File} {} example ('@var{name}') ## @deftypefnx {Function File} {} example ('@var{name}', @var{n}) -## @deftypefnx {Function File} {[@var{x}, @var{idx}] =} example ('@var{name}', @var{n}) +## @deftypefnx {Function File} {[@var{s}, @var{idx}] =} example (@dots{}) ## -## Display the code for example @var{n} associated with the function -## '@var{name}', but do not run it. If @var{n} is not given, all examples +## Display the code for example @var{n} associated with the function +## '@var{name}', but do not run it. If @var{n} is not specified, all examples ## are displayed. ## -## Called with output arguments, the examples are returned in the form of -## a string @var{x}, with @var{idx} indicating the ending position of the +## When called with output arguments, the examples are returned in the form of +## a string @var{s}, with @var{idx} indicating the ending position of the ## various examples. ## ## See @code{demo} for a complete explanation. @@ -41,7 +43,7 @@ if (nargin < 2) n = 0; - elseif (strcmp ("char", class (n))) + elseif (ischar (n)) n = str2double (n); endif @@ -65,15 +67,16 @@ else doidx = 1:length(idx)-1; endif - if (length (idx) == 0) - warning ("example not available for %s", name); + if (isempty (idx)) + warning ("no example available for %s", name); + return; elseif (n >= length(idx)) warning ("only %d examples available for %s", length(idx)-1, name); - doidx = []; + return; endif for i = 1:length (doidx) - block = code (idx(doidx(i)):idx(doidx(i)+1)-1); + block = code(idx(doidx(i)):idx(doidx(i)+1)-1); printf ("%s example %d:%s\n\n", name, doidx(i), block); endfor endif @@ -82,17 +85,18 @@ %!## warning: don't modify the demos without modifying the tests! %!demo -%! example('example'); +%! example ('example'); %!demo -%! t=0:0.01:2*pi; x=sin(t); -%! plot(t,x) +%! t=0:0.01:2*pi; x = sin(t); +%! plot (t,x) -%!assert (example('example',1), "\n example('example');"); +%!assert (example('example',1), "\n example ('example');"); %!test -%! [code, idx] = example('example'); +%! [code, idx] = example ('example'); %! assert (code, ... -%! "\n example('example');\n t=0:0.01:2*pi; x=sin(t);\n plot(t,x)") -%! assert (idx, [1, 22, 59]); +%! "\n example ('example');\n t=0:0.01:2*pi; x = sin(t);\n plot (t,x)") +%! assert (idx, [1, 23, 63]); +%% Test input validation %!error example; -%!error example('example',3,5) +%!error example('example', 3, 5)
--- a/scripts/testfun/rundemos.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/testfun/rundemos.m Fri Aug 12 14:16:34 2011 -0400 @@ -35,6 +35,7 @@ if (is_absolute_filename (directory)) dirs = {directory}; else + directory = regexprep (directory, ['\',filesep(),'$'], ""); fullname = find_dir_in_path (directory); if (! isempty (fullname)) dirs = {fullname};
--- a/scripts/testfun/runtests.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/testfun/runtests.m Fri Aug 12 14:16:34 2011 -0400 @@ -35,6 +35,7 @@ if (is_absolute_filename (directory)) dirs = {directory}; else + directory = regexprep (directory, ['\',filesep(),'$'], ""); fullname = find_dir_in_path (directory); if (! isempty (fullname)) dirs = {fullname};
--- a/scripts/testfun/test.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/testfun/test.m Fri Aug 12 14:16:34 2011 -0400 @@ -132,7 +132,7 @@ __rundemo = 0; __verbose = 0; __demo_code = ""; - __demo_idx = 1; + __demo_idx = []; elseif (strcmp (__flag, "explain")) fprintf (__fid, "# %s new test file\n", __signal_file); fprintf (__fid, "# %s no tests in file\n", __signal_empty); @@ -286,7 +286,7 @@ input ("Press <enter> to continue: ", "s"); catch __success = 0; - __msg = sprintf ("%sdemo failed\n%s", __signal_fail, __error_text__); + __msg = sprintf ("%sdemo failed\n%s", __signal_fail, lasterr ()); end_try_catch clear __test__; @@ -359,7 +359,7 @@ catch __success = 0; __msg = sprintf ("%stest failed: syntax error\n%s", - __signal_fail, __error_text__); + __signal_fail, lasterr ()); end_try_catch endif __code = ""; @@ -389,7 +389,7 @@ catch __success = 0; __msg = sprintf ("%stest failed: syntax error\n%s", - __signal_fail, __error_text__); + __signal_fail, lasterr ()); end_try_catch if (__success) @@ -488,13 +488,13 @@ eval (sprintf ("%s__test__(%s);", __shared_r, __shared)); catch if (strcmp (__type, "xtest")) - __msg = sprintf ("%sknown failure\n%s", __signal_fail, __error_text__); + __msg = sprintf ("%sknown failure\n%s", __signal_fail, lasterr ()); __xfail++; else - __msg = sprintf ("%stest failed\n%s", __signal_fail, __error_text__); + __msg = sprintf ("%stest failed\n%s", __signal_fail, lasterr ()); __success = 0; endif - if (isempty (__error_text__)) + if (isempty (lasterr ())) error ("empty error text, probably Ctrl-C --- aborting"); endif end_try_catch
--- a/scripts/time/now.m Fri Aug 12 14:05:48 2011 -0400 +++ b/scripts/time/now.m Fri Aug 12 14:16:34 2011 -0400 @@ -37,7 +37,11 @@ function t = now () - t = datenum (clock ()); + if (nargin == 0) + t = datenum (clock ()); + else + print_usage (); + endif ## The following doesn't work (e.g., one hour off on 2005-10-04): ## @@ -50,3 +54,8 @@ ## changing by an hour the offset from CUT for part of the year. endfunction + +%!error now (1); +%!assert (isnumeric (now ())); +%!assert (now () > 0); +%!assert (now () <= now ());
--- a/src/DLD-FUNCTIONS/__contourc__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__contourc__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -333,3 +333,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__delaunayn__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__delaunayn__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -226,3 +226,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__dispatch__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__dispatch__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -129,3 +129,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__dsearchn__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__dsearchn__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -108,3 +108,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__fltk_uigetfile__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__fltk_uigetfile__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -130,4 +130,11 @@ return retval; } +/* + +## No test needed for internal helper function. +%!assert (1) + +*/ + #endif
--- a/src/DLD-FUNCTIONS/__glpk__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__glpk__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -854,3 +854,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__init_fltk__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__init_fltk__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -648,13 +648,13 @@ begin (); { + canvas = new + OpenGL_fltk (0, 0, ww , hh - status_h, number ()); + uimenu = new fltk_uimenu(0, 0, ww, menu_h); uimenu->hide (); - canvas = new - OpenGL_fltk (0, 0, ww , hh - status_h, number ()); - bottom = new Fl_Box (0, hh - status_h, @@ -861,8 +861,11 @@ void show_canvas (void) { - canvas->show (); - canvas->make_current (); + if (fp.is_visible ()) + { + canvas->show (); + canvas->make_current (); + } } void hide_canvas (void)
--- a/src/DLD-FUNCTIONS/__lin_interpn__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__lin_interpn__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -355,3 +355,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__magick_read__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__magick_read__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -531,6 +531,13 @@ return output; } +/* + +## No test needed for internal helper function. +%!assert (1) + +*/ + #ifdef HAVE_MAGICK static void @@ -917,6 +924,13 @@ return retval; } +/* + +## No test needed for internal helper function. +%!assert (1) + +*/ + #ifdef HAVE_MAGICK template<class T> @@ -1135,6 +1149,13 @@ return retval; } +/* + +## No test needed for internal helper function. +%!assert (1) + +*/ + #undef GET_PARAM // Determine the file formats supported by GraphicsMagick. This is @@ -1194,3 +1215,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__pchip_deriv__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__pchip_deriv__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -147,3 +147,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__qp__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__qp__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -528,3 +528,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/__voronoi__.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/__voronoi__.cc Fri Aug 12 14:16:34 2011 -0400 @@ -248,3 +248,10 @@ return retval; } + +/* + +## No test needed for internal helper function. +%!assert (1) + +*/
--- a/src/DLD-FUNCTIONS/cellfun.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/cellfun.cc Fri Aug 12 14:16:34 2011 -0400 @@ -58,6 +58,8 @@ #include "ov-uint32.h" #include "ov-uint64.h" +#include "ov-fcn-handle.h" + static octave_value_list get_output_list (octave_idx_type count, octave_idx_type nargout, const octave_value_list& inputlist, @@ -122,8 +124,10 @@ @item ndims\n\ Return the number of dimensions of each element.\n\ \n\ -@item prodofsize\n\ -Return the product of dimensions of each element.\n\ +@item numel\n\ +@itemx prodofsize\n\ +Return the number of elements contained within each cell element. The\n\ +number is the product of the dimensions of the object at each cell element.\n\ \n\ @item size\n\ Return the size along the @var{k}-th dimension.\n\ @@ -142,7 +146,7 @@ \n\ @example\n\ @group\n\ -cellfun (@@atan2, @{1, 0@}, @{0, 1@})\n\ +cellfun (\"atan2\", @{1, 0@}, @{0, 1@})\n\ @result{}ans = [1.57080 0.00000]\n\ @end group\n\ @end example\n\ @@ -177,7 +181,7 @@ \n\ @example\n\ @group\n\ -cellfun (\"tolower(x)\", @{\"Foo\", \"Bar\", \"FooBar\"@},\n\ +cellfun (\"tolower\", @{\"Foo\", \"Bar\", \"FooBar\"@},\n\ \"UniformOutput\",false)\n\ @result{} ans = @{\"foo\", \"bar\", \"foobar\"@}\n\ @end group\n\ @@ -200,7 +204,7 @@ @example\n\ @group\n\ function y = foo (s, x), y = NaN; endfunction\n\ -cellfun (@@factorial, @{-1,2@},'ErrorHandler',@@foo)\n\ +cellfun (\"factorial\", @{-1,2@}, 'ErrorHandler', @@foo)\n\ @result{} ans = [NaN 2]\n\ @end group\n\ @end example\n\ @@ -220,6 +224,7 @@ } octave_value func = args(0); + bool symbol_table_lookup = false; if (! args(1).is_cell ()) { @@ -337,6 +342,8 @@ func = symbol_table::find_function (name); if (func.is_undefined ()) error ("cellfun: invalid function NAME: %s", name.c_str ()); + + symbol_table_lookup = true; } } } @@ -347,6 +354,30 @@ if (func.is_function_handle () || func.is_inline_function () || func.is_function ()) { + + // The following is an optimisation because the symbol table can + // give a more specific function class, so this can result in + // fewer polymorphic function calls as the function gets called + // for each value of the array. + if (! symbol_table_lookup ) + { + if (func.is_function_handle ()) + { + octave_fcn_handle* f = func.fcn_handle_value (); + + // Overloaded function handles need to check the type of + // the arguments for each element of the array, so they + // cannot be optimised this way. + if (f -> is_overloaded ()) + goto nevermind; + } + octave_value f = symbol_table::find_function (func.function_value () + -> name ()); + if (f.is_defined ()) + func = f; + } + nevermind: + unwind_protect frame; frame.protect_var (buffer_error_messages);
--- a/src/DLD-FUNCTIONS/chol.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/chol.cc Fri Aug 12 14:16:34 2011 -0400 @@ -493,9 +493,6 @@ %!testif HAVE_CHOLMOD %! Ainv3 = cholinv(sparse(A)); %! assert (norm(Ainv-Ainv3),0,1e-10) -%!testif HAVE_CHOLMOD -%! Ainv4 = spcholinv(sparse(A)); -%! assert (norm(Ainv-Ainv4),0,1e-10) */
--- a/src/DLD-FUNCTIONS/dot.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/dot.cc Fri Aug 12 14:16:34 2011 -0400 @@ -238,6 +238,17 @@ /* +%! assert(dot ([1, 2], [2, 3]), 11); + +%!test +%! x = [2, 1; 2, 1]; +%! y = [-0.5, 2; 0.5, -2]; +%! assert(dot (x, y), [0 0]); + +%!test +%! x = [ 1+i, 3-i; 1-i, 3-i]; +%! assert(dot (x, x), [4, 20]); + */ DEFUN_DLD (blkmm, args, , @@ -344,3 +355,14 @@ return retval; } + +/* + +%!test +%! x(:,:,1) = [1 2; 3 4]; +%! x(:,:,2) = [1 1; 1 1]; +%! z(:,:,1) = [7 10; 15 22]; +%! z(:,:,2) = [2 2; 2 2]; +%! assert(blkmm (x,x),z); + +*/
--- a/src/DLD-FUNCTIONS/eigs.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/eigs.cc Fri Aug 12 14:16:34 2011 -0400 @@ -323,6 +323,7 @@ bool a_is_complex = false; bool b_is_complex = false; bool symmetric = false; + bool sym_tested = false; bool cholB = false; bool a_is_sparse = false; ColumnVector permB; @@ -399,7 +400,8 @@ else acm = (args(0).complex_matrix_value()); a_is_complex = true; - symmetric = false; // ARAPACK doesn't special case complex symmetric + symmetric = false; // ARPACK doesn't special case complex symmetric + sym_tested = true; } else { @@ -407,19 +409,17 @@ { asmm = (args(0).sparse_matrix_value()); a_is_sparse = true; - symmetric = asmm.is_symmetric(); } else { amm = (args(0).matrix_value()); - symmetric = amm.is_symmetric(); } } } // Note hold off reading B till later to avoid issues of double - // copies of the matrix if B is full/real while A is complex.. + // copies of the matrix if B is full/real while A is complex. if (!error_state && nargin > 1 + arg_offset && !(args(1 + arg_offset).is_real_scalar ())) { @@ -481,10 +481,13 @@ { octave_value tmp; - // issym is ignored if A is not a function + // issym is ignored for complex matrix inputs tmp = map.getfield ("issym"); - if (tmp.is_defined () && have_a_fun) - symmetric = tmp.double_value () != 0.; + if (tmp.is_defined () && !sym_tested) + { + symmetric = tmp.double_value () != 0.; + sym_tested = true; + } // isreal is ignored if A is not a function tmp = map.getfield ("isreal"); @@ -543,6 +546,15 @@ return retval; } + // Test undeclared (no issym) matrix inputs for symmetry + if (!sym_tested && !have_a_fun) + { + if (a_is_sparse) + symmetric = asmm.is_symmetric(); + else + symmetric = amm.is_symmetric(); + } + if (have_b) { if (a_is_complex || b_is_complex)
--- a/src/DLD-FUNCTIONS/filter.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/filter.cc Fri Aug 12 14:16:34 2011 -0400 @@ -104,16 +104,17 @@ return y; } - octave_idx_type si_dim = 0; - for (octave_idx_type i = 0; i < x_dims.length (); i++) + for (octave_idx_type i = 1; i < dim; i++) { - if (i == dim) - continue; - - if (x_dims(i) == 1) - continue; - - if (si_dims(++si_dim) != x_dims(i)) + if (si_dims(i) != x_dims(i-1)) + { + error ("filter: dimensionality of SI and X must agree"); + return y; + } + } + for (octave_idx_type i = dim+1; i < x_dims.length (); i++) + { + if (si_dims(i) != x_dims(i)) { error ("filter: dimensionality of SI and X must agree"); return y; @@ -456,19 +457,10 @@ } else { - dim_vector si_dims = args (3).dims (); - bool si_is_vector = true; - for (int i = 0; i < si_dims.length (); i++) - if (si_dims(i) != 1 && si_dims(i) < si_dims.numel ()) - { - si_is_vector = false; - break; - } - si = args(3).float_complex_array_value (); - if (si_is_vector) - si = si.reshape (dim_vector (1, si.numel ())); + if (si.is_vector () && x.is_vector ()) + si = si.reshape (dim_vector (si.numel (), 1)); } if (! error_state) @@ -513,19 +505,10 @@ } else { - dim_vector si_dims = args (3).dims (); - bool si_is_vector = true; - for (int i = 0; i < si_dims.length (); i++) - if (si_dims(i) != 1 && si_dims(i) < si_dims.numel ()) - { - si_is_vector = false; - break; - } - si = args(3).complex_array_value (); - if (si_is_vector) - si = si.reshape (dim_vector (1, si.numel ())); + if (si.is_vector () && x.is_vector ()) + si = si.reshape (dim_vector (si.numel (), 1)); } if (! error_state) @@ -573,19 +556,10 @@ } else { - dim_vector si_dims = args (3).dims (); - bool si_is_vector = true; - for (int i = 0; i < si_dims.length (); i++) - if (si_dims(i) != 1 && si_dims(i) < si_dims.numel ()) - { - si_is_vector = false; - break; - } - si = args(3).float_array_value (); - if (si_is_vector) - si = si.reshape (dim_vector (1, si.numel ())); + if (si.is_vector () && x.is_vector ()) + si = si.reshape (dim_vector (si.numel (), 1)); } if (! error_state) @@ -630,19 +604,10 @@ } else { - dim_vector si_dims = args (3).dims (); - bool si_is_vector = true; - for (int i = 0; i < si_dims.length (); i++) - if (si_dims(i) != 1 && si_dims(i) < si_dims.numel ()) - { - si_is_vector = false; - break; - } - si = args(3).array_value (); - if (si_is_vector) - si = si.reshape (dim_vector (1, si.numel ())); + if (si.is_vector () && x.is_vector ()) + si = si.reshape (dim_vector (si.numel (), 1)); } if (! error_state) @@ -749,8 +714,20 @@ %! %!assert(filter (1, ones(10,1)/10, []), []); %!assert(filter (1, ones(10,1)/10, zeros(0,10)), zeros(0,10)); +%!assert(filter (1, ones(10,1)/10, single (1:5)), repmat (single (10), 1, 5)); +%% Test using initial conditions +%!assert(filter([1, 1, 1], [1, 1], [1 2], [1, 1]), [2 2]); +%!assert(filter([1, 1, 1], [1, 1], [1 2], [1, 1]'), [2 2]); %!assert(filter([1, 3], [1], [1 2; 3 4; 5 6], [4, 5]), [5 7; 6 10; 14 18]); -%!assert(filter (1, ones(10,1)/10, single (1:5)), repmat (single (10), 1, 5)); -%% Should put some tests of the "DIM" parameter in here. +%!error (filter([1, 3], [1], [1 2; 3 4; 5 6], [4, 5]')); +%!assert(filter([1, 3, 2], [1], [1 2; 3 4; 5 6], [1 0 0; 1 0 0], 2), [2 6; 3 13; 5 21]); +%% Test of DIM parameter +%!test +%! x = ones (2, 1, 3, 4); +%! x(1,1,:,:) = [1 2 3 4; 5 6 7 8; 9 10 11 12]; +%! y0 = [1 1 6 2 15 3 2 1 8 2 18 3 3 1 10 2 21 3 4 1 12 2 24 3]; +%! y0 = reshape (y0, size (x)); +%! y = filter([1 1 1], 1, x, [], 3); +%! assert (y, y0); */
--- a/src/DLD-FUNCTIONS/givens.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/givens.cc Fri Aug 12 14:16:34 2011 -0400 @@ -203,3 +203,13 @@ return retval; } + +/* + +%!assert (givens (1,1), [1, 1; -1, 1]/sqrt(2), 2*eps); +%!assert (givens (1,0), eye(2)); +%!assert (givens (0,1), [0, 1; -1 0]); +%!error givens(1); +%!error givens() + +*/
--- a/src/DLD-FUNCTIONS/kron.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/kron.cc Fri Aug 12 14:16:34 2011 -0400 @@ -264,3 +264,15 @@ return retval; } + +/* + +%!test +%! x = ones(2); +%! assert( kron (x, x), ones (4)); + +%!test +%! z = [1, 2, 3, 4; 1, 2, 3, 4; 1, 2, 3, 4]; +%! assert( kron (1:4, ones (3, 1)), z) + +*/
--- a/src/DLD-FUNCTIONS/qr.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/qr.cc Fri Aug 12 14:16:34 2011 -0400 @@ -76,6 +76,8 @@ "-*- texinfo -*-\n\ @deftypefn {Loadable Function} {[@var{Q}, @var{R}, @var{P}] =} qr (@var{A})\n\ @deftypefnx {Loadable Function} {[@var{Q}, @var{R}, @var{P}] =} qr (@var{A}, '0')\n\ +@deftypefnx {Loadable Function} {[@var{C}, @var{R}] =} qr (@var{A}, @var{B})\n\ +@deftypefnx {Loadable Function} {[@var{C}, @var{R}] =} qr (@var{A}, @var{B}, '0')\n\ @cindex QR factorization\n\ Compute the QR@tie{}factorization of @var{A}, using standard @sc{lapack}\n\ subroutines. For example, given the matrix @code{@var{A} = [1, 2; 3, 4]},\n\ @@ -188,7 +190,7 @@ \n\ @example\n\ @group\n\ -[@var{C},@var{R}] = spqr (@var{A},@var{B})\n\ +[@var{C}, @var{R}] = qr (@var{A}, @var{B})\n\ x = @var{R} \\ @var{C}\n\ @end group\n\ @end example\n\
--- a/src/DLD-FUNCTIONS/quadcc.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/quadcc.cc Fri Aug 12 14:16:34 2011 -0400 @@ -50,8 +50,7 @@ int depth, rdepth, ndiv; } cquad_ival; -/* Some constants and matrices that we'll need. - */ +/* Some constants and matrices that we'll need. */ static const double xi[33] = { -1., -0.99518472667219688624, -0.98078528040323044912, @@ -1473,9 +1472,7 @@ } - -/* The actual integration routine. - */ +/* The actual integration routine. */ DEFUN_DLD (quadcc, args, nargout, "-*- texinfo -*-\n\ @@ -1545,6 +1542,7 @@ @seealso{quad, quadv, quadl, quadgk, trapz, dblquad, triplequad}\n\ @end deftypefn") { + octave_value_list retval; /* Some constants that we will need. */ static const int n[4] = { 4, 8, 16, 32 }; @@ -1563,11 +1561,11 @@ double a, b, tol, iivals[cquad_heapsize], *sing; /* Variables needed for transforming the integrand. */ - int wrap = 0; + bool wrap = false; double xw; /* Stuff we will need to call the integrand. */ - octave_value_list fargs, retval; + octave_value_list fargs, fvals; /* Actual variables (as opposed to constants above). */ double m, h, ml, hl, mr, hr, temp; @@ -1580,48 +1578,49 @@ /* Parse the input arguments. */ - if (nargin < 1) + if (nargin < 3) { - error - ("quadcc: first argument (integrand) of type function handle required"); - return octave_value_list (); + print_usage (); + return retval; } + + if (args(0).is_function_handle () || args(0).is_inline_function ()) + fcn = args(0).function_value (); else { - if (args (0).is_function_handle () || args (0).is_inline_function ()) - fcn = args (0).function_value (); - else - { - error ("quadcc: first argument (integrand) must be a function handle or an inline function"); - return octave_value_list(); - } + std::string fcn_name = unique_symbol_name ("__quadcc_fcn_"); + std::string fname = "function y = "; + fname.append (fcn_name); + fname.append ("(x) y = "); + fcn = extract_function (args(0), "quadcc", fcn_name, fname, + "; endfunction"); } - if (nargin < 2 || !args (1).is_real_scalar ()) + if (!args(1).is_real_scalar ()) { - error ("quadcc: second argument (left interval edge) must be a single real scalar"); - return octave_value_list (); + error ("quadcc: lower limit of integration (A) must be a single real scalar"); + return retval; } else - a = args (1).double_value (); + a = args(1).double_value (); - if (nargin < 3 || !args (2).is_real_scalar ()) + if (!args(2).is_real_scalar ()) { - error ("quadcc: third argument (right interval edge) must be a single real scalar"); - return octave_value_list (); + error ("quadcc: upper limit of integration (B) must be a single real scalar"); + return retval; } else - b = args (2).double_value (); + b = args(2).double_value (); - if (nargin < 4) + if (nargin < 4 || args(3).is_empty ()) tol = 1.0e-6; - else if (!args (3).is_real_scalar ()) + else if (!args(3).is_real_scalar () || args(3).double_value () <= 0) { - error ("quadcc: fourth argument (tolerance) must be a single real scalar"); - return octave_value_list (); + error ("quadcc: tolerance (TOL) must be a single real scalar > 0"); + return retval; } else - tol = args (3).double_value (); + tol = args(3).double_value (); if (nargin < 5) { @@ -1629,20 +1628,21 @@ iivals[0] = a; iivals[1] = b; } - else if (!(args (4).is_real_scalar () || args (4).is_real_matrix ())) + else if (!(args(4).is_real_scalar () || args(4).is_real_matrix ())) { - error ("quadcc: fifth argument (singularities) must be a vector of real values"); - return octave_value_list (); + error ("quadcc: list of singularities (SING) must be a vector of real values"); + return retval; } else { - nivals = 1 + args (4).length (); - if ( nivals > cquad_heapsize ) { - error ("quadcc: maximum number of singular points is limited to %i", - cquad_heapsize-1); - return octave_value_list(); + nivals = 1 + args(4).length (); + if (nivals > cquad_heapsize) + { + error ("quadcc: maximum number of singular points is limited to %i", + cquad_heapsize-1); + return retval; } - sing = args (4).array_value ().fortran_vec (); + sing = args(4).array_value ().fortran_vec (); iivals[0] = a; for (i = 0; i < nivals - 2; i++) iivals[i + 1] = sing[i]; @@ -1652,7 +1652,7 @@ /* If a or b are +/-Inf, transform the integral. */ if (xisinf (a) || xisinf (b)) { - wrap = 1; + wrap = true; for (i = 0; i <= nivals; i++) if (xisinf (iivals[i])) iivals[i] = copysign (1.0, iivals[i]); @@ -1688,19 +1688,18 @@ for (i = 0; i <= n[3]; i++) ex (i) = m + xi[i] * h; } - fargs (0) = ex; - retval = feval (fcn, fargs, 1); - if (retval.length () != 1 || !retval (0).is_real_matrix ()) + fargs(0) = ex; + fvals = feval (fcn, fargs, 1); + if (fvals.length () != 1 || !fvals(0).is_real_matrix ()) { - error - ("quadcc: integrand must return a single, real-valued vector"); - return octave_value_list (); + error ("quadcc: integrand F must return a single, real-valued vector"); + return retval; } - Matrix effex = retval (0).matrix_value (); + Matrix effex = fvals(0).matrix_value (); if (effex.length () != ex.length ()) { - error ("quadcc: integrand must return a single, real-valued vector of the same size as the input"); - return octave_value_list (); + error ("quadcc: integrand F must return a single, real-valued vector of the same size as the input"); + return retval; } for (i = 0; i <= n[3]; i++) { @@ -1809,18 +1808,18 @@ for (i = 0; i < n[d] / 2; i++) ex (i) = m + xi[(2 * i + 1) * skip[d]] * h; } - fargs (0) = ex; - retval = feval (fcn, fargs, 1); - if (retval.length () != 1 || !retval (0).is_real_matrix ()) + fargs(0) = ex; + fvals = feval (fcn, fargs, 1); + if (fvals.length () != 1 || !fvals(0).is_real_matrix ()) { - error ("quadcc: integrand must return a single, real-valued vector"); - return octave_value_list (); + error ("quadcc: integrand F must return a single, real-valued vector"); + return retval; } - Matrix effex = retval (0).matrix_value (); + Matrix effex = fvals(0).matrix_value (); if (effex.length () != ex.length ()) { - error ("quadcc: integrand must return a single, real-valued vector of the same size as the input"); - return octave_value_list (); + error ("quadcc: integrand F must return a single, real-valued vector of the same size as the input"); + return retval; } neval += effex.length (); for (i = 0; i < n[d] / 2; i++) @@ -1957,18 +1956,18 @@ for (i = 0; i < n[0] - 1; i++) ex (i) = ml + xi[(i + 1) * skip[0]] * hl; } - fargs (0) = ex; - retval = feval (fcn, fargs, 1); - if (retval.length () != 1 || !retval (0).is_real_matrix ()) + fargs(0) = ex; + fvals = feval (fcn, fargs, 1); + if (fvals.length () != 1 || !fvals(0).is_real_matrix ()) { - error ("quadcc: integrand must return a single, real-valued vector"); - return octave_value_list (); + error ("quadcc: integrand F must return a single, real-valued vector"); + return retval; } - Matrix effex = retval (0).matrix_value (); + Matrix effex = fvals(0).matrix_value (); if (effex.length () != ex.length ()) { - error ("quadcc: integrand must return a single, real-valued vector of the same size as the input"); - return octave_value_list (); + error ("quadcc: integrand F must return a single, real-valued vector of the same size as the input"); + return retval; } neval += effex.length (); for (i = 0; i < n[0] - 1; i++) @@ -2053,18 +2052,18 @@ for (i = 0; i < n[0] - 1; i++) ex (i) = mr + xi[(i + 1) * skip[0]] * hr; } - fargs (0) = ex; - retval = feval (fcn, fargs, 1); - if (retval.length () != 1 || !retval (0).is_real_matrix ()) + fargs(0) = ex; + fvals = feval (fcn, fargs, 1); + if (fvals.length () != 1 || !fvals(0).is_real_matrix ()) { - error ("quadcc: integrand must return a single, real-valued vector"); - return octave_value_list (); + error ("quadcc: integrand F must return a single, real-valued vector"); + return retval; } - Matrix effex = retval (0).matrix_value (); + Matrix effex = fvals(0).matrix_value (); if (effex.length () != ex.length ()) { - error ("quadcc: integrand must return a single, real-valued vector of the same size as the input"); - return octave_value_list (); + error ("quadcc: integrand F must return a single, real-valued vector of the same size as the input"); + return retval; } neval += effex.length (); for (i = 0; i < n[0] - 1; i++) @@ -2234,11 +2233,39 @@ } */ /* Clean up and present the results. */ - retval (0) = igral; + if (nargout > 2) + retval(2) = neval; if (nargout > 1) - retval (1) = err; - if (nargout > 2) - retval (2) = neval; + retval(1) = err; + retval(0) = igral; /* All is well that ends well. */ return retval; } + + +/* + +%!assert (quadcc(@sin,-pi,pi), 0, 1e-6) +%!assert (quadcc(inline('sin'),-pi,pi), 0, 1e-6) +%!assert (quadcc('sin',-pi,pi), 0, 1e-6) + +%!assert (quadcc(@sin,-pi,0), -2, 1e-6) +%!assert (quadcc(@sin,0,pi), 2, 1e-6) +%!assert (quadcc(@(x) 1./sqrt(x), 0, 1), 2, 1e-6) +%!assert (quadcc(@(x) 1./(sqrt(x).*(x+1)), 0, Inf), pi, 1e-6) + +%!assert (quadcc (@(x) exp(-x .^ 2), -Inf, Inf), sqrt(pi), 1e-6) +%!assert (quadcc (@(x) exp(-x .^ 2), -Inf, 0), sqrt(pi)/2, 1e-6) + +%% Test input validation +%!error (quadcc ()) +%!error (quadcc (@sin)) +%!error (quadcc (@sin, 0)) +%!error (quadcc (@sin, ones(2), pi)) +%!error (quadcc (@sin, -i, pi)) +%!error (quadcc (@sin, 0, ones(2))) +%!error (quadcc (@sin, 0, i)) +%!error (quadcc (@sin, 0, pi, 0)) +%!error (quadcc (@sin, 0, pi, 1e-6, [ i ])) + +*/
--- a/src/DLD-FUNCTIONS/rand.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/rand.cc Fri Aug 12 14:16:34 2011 -0400 @@ -179,18 +179,16 @@ octave_idx_type incr = NINTbig (r.inc ()); octave_idx_type lim = NINTbig (r.limit ()); - if (base < 0 || lim < 0) - error ("%s: all dimensions must be positive", fcn); - else + for (octave_idx_type i = 0; i < n; i++) { - for (octave_idx_type i = 0; i < n; i++) - { - dims(i) = base; - base += incr; - } + //Negative dimensions are treated as zero for Matlab + //compatibility + dims(i) = base >= 0 ? base : 0; + base += incr; + } - goto gen_matrix; - } + goto gen_matrix; + } else error ("%s: all elements of range must be integers", @@ -208,15 +206,10 @@ for (octave_idx_type i = 0; i < len; i++) { + //Negative dimensions are treated as zero for Matlab + //compatibility octave_idx_type elt = iv(i); - - if (elt < 0) - { - error ("%s: all dimensions must be positive", fcn); - goto done; - } - - dims(i) = iv(i); + dims(i) = elt >=0 ? elt : 0; } goto gen_matrix; @@ -278,13 +271,14 @@ for (int i = 0; i < nargin; i++) { - dims(i) = args(idx+i).int_value (); - + octave_idx_type elt = args(idx+i).int_value (); if (error_state) { error ("%s: expecting integer arguments", fcn); goto done; } + //Negative is zero for Matlab compatibility + dims(i) = elt >= 0 ? elt : 0; } goto gen_matrix;
--- a/src/DLD-FUNCTIONS/rcond.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/rcond.cc Fri Aug 12 14:16:34 2011 -0400 @@ -85,3 +85,12 @@ return retval; } + +/* + +%!assert( rcond (eye (2)), 1) +%!assert( rcond (ones (2)), 0) +%!assert( rcond ([1 1; 2 1]), 1/9) +%!assert( rcond (magic (4)), 0, eps) + +*/
--- a/src/DLD-FUNCTIONS/sqrtm.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/sqrtm.cc Fri Aug 12 14:16:34 2011 -0400 @@ -49,22 +49,20 @@ bool singular = false; - /* - * the following code is equivalent to this triple loop: - * - * n = rows (T); - * for j = 1:n - * T(j,j) = sqrt (T(j,j)); - * for i = j-1:-1:1 - * T(i,j) /= (T(i,i) + T(j,j)); - * k = 1:i-1; - * T(k,j) -= T(k,i) * T(i,j); - * endfor - * endfor - * - * this is an in-place, cache-aligned variant of the code - * given in Higham's paper. - */ + // The following code is equivalent to this triple loop: + // + // n = rows (T); + // for j = 1:n + // T(j,j) = sqrt (T(j,j)); + // for i = j-1:-1:1 + // T(i,j) /= (T(i,i) + T(j,j)); + // k = 1:i-1; + // T(k,j) -= T(k,i) * T(i,j); + // endfor + // endfor + // + // this is an in-place, cache-aligned variant of the code + // given in Higham's paper. const octave_idx_type n = T.rows (); element_type *Tp = T.fortran_vec (); @@ -117,38 +115,32 @@ { case MatrixType::Upper: case MatrixType::Diagonal: - { - if (! x.diag ().any_element_is_negative ()) - { - // Do it in real arithmetic. - sqrtm_utri_inplace (x); - retval = x; - retval.matrix_type (mt); - } - else - iscomplex = true; - - break; - } - case MatrixType::Lower: + if (! x.diag ().any_element_is_negative ()) { - if (! x.diag ().any_element_is_negative ()) - { - x = x.transpose (); - sqrtm_utri_inplace (x); - retval = x.transpose (); - retval.matrix_type (mt); - } - else - iscomplex = true; + // Do it in real arithmetic. + sqrtm_utri_inplace (x); + retval = x; + retval.matrix_type (mt); + } + else + iscomplex = true; + break; - break; + case MatrixType::Lower: + if (! x.diag ().any_element_is_negative ()) + { + x = x.transpose (); + sqrtm_utri_inplace (x); + retval = x.transpose (); + retval.matrix_type (mt); } + else + iscomplex = true; + break; + default: - { - iscomplex = true; - break; - } + iscomplex = true; + break; } if (iscomplex) @@ -166,46 +158,41 @@ { case MatrixType::Upper: case MatrixType::Diagonal: - { - sqrtm_utri_inplace (x); - retval = x; - retval.matrix_type (mt); + sqrtm_utri_inplace (x); + retval = x; + retval.matrix_type (mt); + break; - break; - } case MatrixType::Lower: - { - x = x.transpose (); - sqrtm_utri_inplace (x); - retval = x.transpose (); - retval.matrix_type (mt); + x = x.transpose (); + sqrtm_utri_inplace (x); + retval = x.transpose (); + retval.matrix_type (mt); + break; - break; - } default: - { - ComplexMatrix u; + { + ComplexMatrix u; - do - { - ComplexSCHUR schur (x, std::string (), true); - x = schur.schur_matrix (); - u = schur.unitary_matrix (); - } - while (0); // schur no longer needed. + do + { + ComplexSCHUR schur (x, std::string (), true); + x = schur.schur_matrix (); + u = schur.unitary_matrix (); + } + while (0); // schur no longer needed. - sqrtm_utri_inplace (x); + sqrtm_utri_inplace (x); - x = u * x; // original x no longer needed. - ComplexMatrix res = xgemm (x, u, blas_no_trans, blas_conj_trans); + x = u * x; // original x no longer needed. + ComplexMatrix res = xgemm (x, u, blas_no_trans, blas_conj_trans); - if (cutoff > 0 && xnorm (imag (res), one) <= cutoff) - retval = real (res); - else - retval = res; - - break; - } + if (cutoff > 0 && xnorm (imag (res), one) <= cutoff) + retval = real (res); + else + retval = res; + } + break; } } @@ -246,22 +233,17 @@ } if (arg.is_diag_matrix ()) - { - // sqrtm of a diagonal matrix is just sqrt. - retval(0) = arg.sqrt (); - } + // sqrtm of a diagonal matrix is just sqrt. + retval(0) = arg.sqrt (); else if (arg.is_single_type ()) - { - retval(0) = do_sqrtm<FloatMatrix, FloatComplexMatrix, FloatComplexSCHUR> (arg); - } + retval(0) = do_sqrtm<FloatMatrix, FloatComplexMatrix, FloatComplexSCHUR> (arg); else if (arg.is_numeric_type ()) - { - retval(0) = do_sqrtm<Matrix, ComplexMatrix, ComplexSCHUR> (arg); - } + retval(0) = do_sqrtm<Matrix, ComplexMatrix, ComplexSCHUR> (arg); if (nargout > 1 && ! error_state) { // This corresponds to generic code + // // norm (s*s - x, "fro") / norm (x, "fro"); octave_value s = retval(0); @@ -270,3 +252,22 @@ return retval; } + +/* + +%!assert (sqrtm (2*ones (2)), ones (2), 3*eps) + +## The following two tests are from the reference in the docstring above. + +%!test +%! x = [0 1; 0 0]; +%! assert (any (isnan (sqrtm (x))(:) )) + +%!test +%! x = eye (4); x(2,2) = x(3,3) = 2^-26; x(1,4) = 1; +%! z = eye (4); z(2,2) = z(3,3) = 2^-13; z(1,4) = 0.5; +%! [y, err] = sqrtm(x); +%! assert (y, z) +%! assert (err, 0) ## Yes, this one has to hold exactly + +*/
--- a/src/DLD-FUNCTIONS/urlwrite.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/DLD-FUNCTIONS/urlwrite.cc Fri Aug 12 14:16:34 2011 -0400 @@ -52,7 +52,6 @@ #include <curl/curl.h> #include <curl/curlver.h> -#include <curl/types.h> #include <curl/easy.h> static int
--- a/src/Makefile.am Fri Aug 12 14:05:48 2011 -0400 +++ b/src/Makefile.am Fri Aug 12 14:16:34 2011 -0400 @@ -310,6 +310,7 @@ defaults.h \ graphics.h \ oct-conf.h \ + profiler.h \ mxarray.h \ version.h @@ -446,6 +447,7 @@ pager.cc \ pr-output.cc \ procstream.cc \ + profiler.cc \ sighandlers.cc \ siglist.c \ sparse.cc \
--- a/src/data.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/data.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1943,6 +1943,9 @@ %!error <dimension mismatch> cat (3, cat (3, [], []), [1,2;3,4]); %!error <dimension mismatch> cat (3, zeros (0, 0, 2), [1,2;3,4]); +%!assert ([zeros(3,2,2); ones(1,2,2)], repmat([0;0;0;1],[1,2,2]) ); +%!assert ([zeros(3,2,2); ones(1,2,2)], vertcat(zeros(3,2,2), ones(1,2,2)) ); + */ static octave_value @@ -4194,8 +4197,8 @@ @end example\n\ \n\ Calling @code{eye} with no arguments is equivalent to calling it\n\ -with an argument of 1. This odd definition is for compatibility\n\ -with @sc{matlab}.\n\ +with an argument of 1. Any negative dimensions are treated as zero. \n\ +These odd definitions are for compatibility with @sc{matlab}.\n\ @seealso{speye}\n\ @end deftypefn") {
--- a/src/defaults.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/defaults.cc Fri Aug 12 14:16:34 2011 -0400 @@ -419,6 +419,17 @@ return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (EDITOR); } +/* +%!error (EDITOR (1, 2)); +%!test +%! orig_val = EDITOR (); +%! old_val = EDITOR ("X"); +%! assert (orig_val, old_val); +%! assert (EDITOR (), "X"); +%! EDITOR (orig_val); +%! assert (EDITOR (), orig_val); +*/ + DEFUN (EXEC_PATH, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} EXEC_PATH ()\n\ @@ -438,6 +449,17 @@ return retval; } +/* +%!error (EXEC_PATH (1, 2)); +%!test +%! orig_val = EXEC_PATH (); +%! old_val = EXEC_PATH ("X"); +%! assert (orig_val, old_val); +%! assert (EXEC_PATH (), "X"); +%! EXEC_PATH (orig_val); +%! assert (EXEC_PATH (), orig_val); +*/ + DEFUN (IMAGE_PATH, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} IMAGE_PATH ()\n\ @@ -449,6 +471,17 @@ return SET_NONEMPTY_INTERNAL_STRING_VARIABLE (IMAGE_PATH); } +/* +%!error (IMAGE_PATH (1, 2)); +%!test +%! orig_val = IMAGE_PATH (); +%! old_val = IMAGE_PATH ("X"); +%! assert (orig_val, old_val); +%! assert (IMAGE_PATH (), "X"); +%! IMAGE_PATH (orig_val); +%! assert (IMAGE_PATH (), orig_val); +*/ + DEFUN (OCTAVE_HOME, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} OCTAVE_HOME ()\n\ @@ -465,6 +498,11 @@ return retval; } +/* +%!error OCTAVE_HOME (1); +%!assert (ischar (OCTAVE_HOME ())); +*/ + DEFUNX ("OCTAVE_VERSION", FOCTAVE_VERSION, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} OCTAVE_VERSION ()\n\ @@ -482,3 +520,8 @@ return retval; } + +/* +%!error OCTAVE_VERSION (1); +%!assert (ischar (OCTAVE_VERSION ())); +*/
--- a/src/error.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/error.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1066,6 +1066,10 @@ octave_scalar_map m = args(0).scalar_map_value (); + // empty struct is not an error. return and resume calling function. + if (m.nfields () == 0) + return retval; + if (m.contains ("message")) { octave_value c = m.getfield ("message"); @@ -1684,10 +1688,6 @@ return retval; } -// For backward compatibility. -DEFALIAS (error_text, lasterr); -DEFALIAS (__error_text__, lasterr); - DEFUN (lastwarn, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {[@var{msg}, @var{msgid}] =} lastwarn (@var{msg}, @var{msgid})\n\
--- a/src/gl-render.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/gl-render.cc Fri Aug 12 14:16:34 2011 -0400 @@ -665,7 +665,7 @@ double p1, double p1N, double p2, double p2N, double dx, double dy, double dz, - int xyz, bool doubleside) + int xyz, bool mirror) { glBegin (GL_LINES); @@ -679,7 +679,7 @@ { glVertex3d (val, p1, p2); glVertex3d (val, p1+dy, p2+dz); - if (doubleside) + if (mirror) { glVertex3d (val, p1N, p2N); glVertex3d (val, p1N-dy, p2N-dz); @@ -689,7 +689,7 @@ { glVertex3d (p1, val, p2); glVertex3d (p1+dx, val, p2+dz); - if (doubleside) + if (mirror) { glVertex3d (p1N, val, p2N); glVertex3d (p1N-dx, val, p2N-dz); @@ -699,7 +699,7 @@ { glVertex3d (p1, p2, val); glVertex3d (p1+dx, p2+dy, val); - if (doubleside) + if (mirror) { glVertex3d (p1N, p2N, val); glVertex3d (p1N-dx, p2N-dy, val); @@ -966,7 +966,7 @@ string_vector xticklabels = props.get_xticklabel ().all_strings (); int wmax = 0, hmax = 0; bool tick_along_z = nearhoriz || xisinf (fy); - bool box = props.is_box (); + bool mirror = props.is_box () && xstate != AXE_ANY_DIR; set_color (props.get_xcolor_rgb ()); @@ -982,14 +982,14 @@ render_tickmarks (xticks, x_min, x_max, ypTick, ypTick, zpTick, zpTickN, 0., 0., signum(zpTick-zpTickN)*fz*xticklen, - 0, (box && xstate != AXE_ANY_DIR)); + 0, mirror); } else { render_tickmarks (xticks, x_min, x_max, ypTick, ypTickN, zpTick, zpTick, 0., signum(ypTick-ypTickN)*fy*xticklen, - 0., 0, (box && xstate != AXE_ANY_DIR)); + 0., 0, mirror); } // tick texts @@ -1021,12 +1021,12 @@ render_tickmarks (xmticks, x_min, x_max, ypTick, ypTick, zpTick, zpTickN, 0., 0., signum(zpTick-zpTickN)*fz*xticklen/2, - 0, (box && xstate != AXE_ANY_DIR)); + 0, mirror); else render_tickmarks (xmticks, x_min, x_max, ypTick, ypTickN, zpTick, zpTick, 0., signum(ypTick-ypTickN)*fy*xticklen/2, - 0., 0, (box && xstate != AXE_ANY_DIR)); + 0., 0, mirror); } gh_manager::get_object (props.get_xlabel ()).set ("visible", "on"); @@ -1073,7 +1073,8 @@ string_vector yticklabels = props.get_yticklabel ().all_strings (); int wmax = 0, hmax = 0; bool tick_along_z = nearhoriz || xisinf (fx); - bool box = props.is_box (); + bool mirror = props.is_box () && ystate != AXE_ANY_DIR + && (props.get_tag () != "plotyy"); set_color (props.get_ycolor_rgb ()); @@ -1088,12 +1089,12 @@ render_tickmarks (yticks, y_min, y_max, xpTick, xpTick, zpTick, zpTickN, 0., 0., signum(zpTick-zpTickN)*fz*yticklen, - 1, (box && ystate != AXE_ANY_DIR)); + 1, mirror); else render_tickmarks (yticks, y_min, y_max, xpTick, xpTickN, zpTick, zpTick, signum(xPlaneN-xPlane)*fx*yticklen, - 0., 0., 1, (box && ystate != AXE_ANY_DIR)); + 0., 0., 1, mirror); // tick texts if (yticklabels.numel () > 0) @@ -1125,12 +1126,12 @@ render_tickmarks (ymticks, y_min, y_max, xpTick, xpTick, zpTick, zpTickN, 0., 0., signum(zpTick-zpTickN)*fz*yticklen/2, - 1, (box && ystate != AXE_ANY_DIR)); + 1, mirror); else render_tickmarks (ymticks, y_min, y_max, xpTick, xpTickN, zpTick, zpTick, signum(xpTick-xpTickN)*fx*yticklen/2, - 0., 0., 1, (box && ystate != AXE_ANY_DIR)); + 0., 0., 1, mirror); } gh_manager::get_object (props.get_ylabel ()).set ("visible", "on"); @@ -1169,7 +1170,7 @@ Matrix zmticks = xform.zscale (props.get_zmtick ().matrix_value ()); string_vector zticklabels = props.get_zticklabel ().all_strings (); int wmax = 0, hmax = 0; - bool box = props.is_box (); + bool mirror = props.is_box () && zstate != AXE_ANY_DIR; set_color (props.get_zcolor_rgb ()); @@ -1185,7 +1186,7 @@ render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane, yPlane, yPlane, signum(xPlaneN-xPlane)*fx*zticklen, - 0., 0., 2, (box && zstate != AXE_ANY_DIR)); + 0., 0., 2, mirror); else render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlaneN, yPlane, yPlane, 0., @@ -1198,7 +1199,7 @@ render_tickmarks (zticks, z_min, z_max, xPlaneN, xPlane, yPlaneN, yPlane, 0., signum(yPlaneN-yPlane)*fy*zticklen, - 0., 2, (box && zstate != AXE_ANY_DIR)); + 0., 2, mirror); else render_tickmarks (zticks, z_min, z_max, xPlane, xPlane, yPlaneN, yPlane, @@ -1250,7 +1251,7 @@ render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlane, yPlane, yPlane, signum(xPlaneN-xPlane)*fx*zticklen/2, - 0., 0., 2, (box && zstate != AXE_ANY_DIR)); + 0., 0., 2, mirror); else render_tickmarks (zmticks, z_min, z_max, xPlaneN, xPlaneN, yPlane, yPlane, 0., @@ -1263,7 +1264,7 @@ render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane, yPlaneN, yPlane, 0., signum(yPlaneN-yPlane)*fy*zticklen/2, - 0., 2, (box && zstate != AXE_ANY_DIR)); + 0., 2, mirror); else render_tickmarks (zmticks, z_min, z_max, xPlane, xPlane, yPlaneN, yPlaneN,
--- a/src/graphics.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/graphics.cc Fri Aug 12 14:16:34 2011 -0400 @@ -3172,6 +3172,7 @@ ticklength.add_constraint (dim_vector (1, 2)); tightinset.add_constraint (dim_vector (1, 4)); looseinset.add_constraint (dim_vector (1, 4)); + update_font (); x_zlim.resize (1, 2); @@ -3263,13 +3264,119 @@ void axes::properties::sync_positions (void) { + Matrix ref_linset = looseinset.get ().matrix_value (); + if (autopos_tag_is ("subplot")) + { + graphics_object parent_obj = gh_manager::get_object (get_parent ()); + if (parent_obj.isa ("figure")) + { + // FIXME: temporarily changed units should be protected + // from interrupts + std::string fig_units = parent_obj.get ("units").string_value (); + parent_obj.set ("units", "pixels"); + + Matrix ref_outbox = outerposition.get ().matrix_value (); + ref_outbox(2) += ref_outbox(0); + ref_outbox(3) += ref_outbox(1); + + // Find those subplots that are left, right, bottom and top aligned + // with the current subplot + Matrix kids = parent_obj.get_properties ().get_children (); + std::vector<octave_value> aligned; + std::vector<bool> l_aligned, b_aligned, r_aligned, t_aligned; + for (octave_idx_type i = 0; i < kids.numel (); i++) + { + graphics_object go = gh_manager::get_object (kids(i)); + if (go.isa ("axes")) + { + axes::properties& props = + dynamic_cast<axes::properties&> (go.get_properties ()); + if (props.autopos_tag_is("subplot")) + { + Matrix outpos = go.get ("outerposition").matrix_value (); + bool l_align=(std::abs (outpos(0)-ref_outbox(0)) < 1e-15); + bool b_align=(std::abs (outpos(1)-ref_outbox(1)) < 1e-15); + bool r_align=(std::abs (outpos(0)+outpos(2)-ref_outbox(2)) < 1e-15); + bool t_align=(std::abs (outpos(1)+outpos(3)-ref_outbox(3)) < 1e-15); + if (l_align || b_align || r_align || t_align) + { + aligned.push_back(kids(i)); + l_aligned.push_back(l_align); + b_aligned.push_back(b_align); + r_aligned.push_back(r_align); + t_aligned.push_back(t_align); + // FIXME: the temporarily deleted tags should be + // protected from interrupts + props.set_autopos_tag ("none"); + } + } + } + } + // Determine a minimum box which aligns the subplots + Matrix ref_box(1, 4, 0.); + ref_box(2) = 1.; + ref_box(3) = 1.; + for (size_t i = 0; i < aligned.size (); i++) + { + graphics_object go = gh_manager::get_object (aligned[i]); + axes::properties& props = + dynamic_cast<axes::properties&> (go.get_properties ()); + Matrix linset = props.get_looseinset ().matrix_value (); + if (l_aligned[i]) + linset(0) = std::min (0., linset(0)-0.01); + if (b_aligned[i]) + linset(1) = std::min (0., linset(1)-0.01); + if (r_aligned[i]) + linset(2) = std::min (0., linset(2)-0.01); + if (t_aligned[i]) + linset(3) = std::min (0., linset(3)-0.01); + props.set_looseinset (linset); + Matrix pos = props.get_position ().matrix_value (); + if (l_aligned[i]) + ref_box(0) = std::max (ref_box(0), pos(0)); + if (b_aligned[i]) + ref_box(1) = std::max (ref_box(1), pos(1)); + if (r_aligned[i]) + ref_box(2) = std::min (ref_box(2), pos(0)+pos(2)); + if (t_aligned[i]) + ref_box(3) = std::min (ref_box(3), pos(1)+pos(3)); + } + // Set common looseinset values for all aligned subplots and + // revert their tag values + for (size_t i = 0; i < aligned.size (); i++) + { + graphics_object go = gh_manager::get_object (aligned[i]); + axes::properties& props = + dynamic_cast<axes::properties&> (go.get_properties ()); + Matrix outpos = props.get_outerposition ().matrix_value (); + Matrix linset = props.get_looseinset ().matrix_value (); + if (l_aligned[i]) + linset(0) = (ref_box(0)-outpos(0))/outpos(2); + if (b_aligned[i]) + linset(1) = (ref_box(1)-outpos(1))/outpos(3); + if (r_aligned[i]) + linset(2) = (outpos(0)+outpos(2)-ref_box(2))/outpos(2); + if (t_aligned[i]) + linset(3) = (outpos(1)+outpos(3)-ref_box(3))/outpos(3); + props.set_looseinset (linset); + props.set_autopos_tag ("subplot"); + } + parent_obj.set ("units", fig_units); + } + } + else + sync_positions (ref_linset); +} + +void +axes::properties::sync_positions (const Matrix& linset) +{ Matrix pos = position.get ().matrix_value (); Matrix outpos = outerposition.get ().matrix_value (); - Matrix lins = looseinset.get ().matrix_value (); - double lratio = lins(0); - double bratio = lins(1); - double wratio = 1-lins(0)-lins(2); - double hratio = 1-lins(1)-lins(3); + double lratio = linset(0); + double bratio = linset(1); + double wratio = 1-linset(0)-linset(2); + double hratio = 1-linset(1)-linset(3); if (activepositionproperty.is ("outerposition")) { pos = outpos; @@ -4223,15 +4330,22 @@ update_title_position (); } +static bool updating_xlabel_position = false; + void axes::properties::update_xlabel_position (void) { + if (updating_xlabel_position) + return; + text::properties& xlabel_props = reinterpret_cast<text::properties&> (gh_manager::get_object (get_xlabel ()).get_properties ()); bool is_empty = xlabel_props.get_string ().empty (); - xlabel_props.set_autopos_tag ("none"); + unwind_protect frame; + frame.protect_var (updating_xlabel_position); + updating_xlabel_position = true; if (! is_empty) { @@ -4305,19 +4419,24 @@ xlabel_props.set_rotationmode ("auto"); } } - - xlabel_props.set_autopos_tag ("xlabel"); -} +} + +static bool updating_ylabel_position = false; void axes::properties::update_ylabel_position (void) { + if (updating_ylabel_position) + return; + text::properties& ylabel_props = reinterpret_cast<text::properties&> (gh_manager::get_object (get_ylabel ()).get_properties ()); bool is_empty = ylabel_props.get_string ().empty (); - ylabel_props.set_autopos_tag ("none"); + unwind_protect frame; + frame.protect_var (updating_ylabel_position); + updating_ylabel_position = true; if (! is_empty) { @@ -4391,20 +4510,25 @@ ylabel_props.set_rotationmode ("auto"); } } - - ylabel_props.set_autopos_tag ("ylabel"); -} +} + +static bool updating_zlabel_position = false; void axes::properties::update_zlabel_position (void) { + if (updating_zlabel_position) + return; + text::properties& zlabel_props = reinterpret_cast<text::properties&> (gh_manager::get_object (get_zlabel ()).get_properties ()); bool camAuto = cameraupvectormode_is ("auto"); bool is_empty = zlabel_props.get_string ().empty (); - zlabel_props.set_autopos_tag ("none"); + unwind_protect frame; + frame.protect_var (updating_zlabel_position); + updating_zlabel_position = true; if (! is_empty) { @@ -4499,17 +4623,22 @@ zlabel_props.set_rotationmode ("auto"); } } - - zlabel_props.set_autopos_tag ("zlabel"); -} +} + +static bool updating_title_position = false; void axes::properties::update_title_position (void) { + if (updating_title_position) + return; + text::properties& title_props = reinterpret_cast<text::properties&> (gh_manager::get_object (get_title ()).get_properties ()); - title_props.set_autopos_tag ("none"); + unwind_protect frame; + frame.protect_var (updating_title_position); + updating_title_position = true; if (title_props.positionmode_is ("auto")) { @@ -4523,8 +4652,6 @@ title_props.set_position (p.extract_n(0, 3).transpose ()); title_props.set_positionmode ("auto"); } - - title_props.set_autopos_tag ("title"); } void @@ -4693,6 +4820,19 @@ } } +void +axes::properties::update_font (void) +{ +#ifdef HAVE_FREETYPE +#ifdef HAVE_FONTCONFIG + text_renderer.set_font (get ("fontname").string_value (), + get ("fontweight").string_value (), + get ("fontangle").string_value (), + get ("fontsize").double_value ()); +#endif +#endif +} + // The INTERNAL flag defines whether position or outerposition is used. Matrix @@ -5196,14 +5336,7 @@ const string_vector& ticklabels, const Matrix& limits) { -#ifdef HAVE_FREETYPE - //FIXME: text_renderer could be cached - ft_render text_renderer; - text_renderer.set_font (get ("fontname").string_value (), - get ("fontweight").string_value (), - get ("fontangle").string_value (), - get ("fontsize").double_value ()); -#else +#ifndef HAVE_FREETYPE double fontsize = get ("fontsize").double_value (); #endif @@ -5856,11 +5989,9 @@ } void -text::properties::update_text_extent (void) +text::properties::update_font (void) { #ifdef HAVE_FREETYPE - - // FIXME: font and color should be set only when modified, for efficiency #ifdef HAVE_FONTCONFIG renderer.set_font (get ("fontname").string_value (), get ("fontweight").string_value (), @@ -5868,7 +5999,13 @@ get ("fontsize").double_value ()); #endif renderer.set_color (get_color_rgb ()); - +#endif +} + +void +text::properties::update_text_extent (void) +{ +#ifdef HAVE_FREETYPE int halign = 0, valign = 0; if (horizontalalignment_is ("center")) @@ -6909,6 +7046,12 @@ if (nargin == 1 || nargin == 2) { + if (args(0).is_empty()) + { + retval = Matrix (); + return retval; + } + ColumnVector hcv (args(0).vector_value ()); if (! error_state)
--- a/src/graphics.h.in Fri Aug 12 14:05:48 2011 -0400 +++ b/src/graphics.h.in Fri Aug 12 14:16:34 2011 -0400 @@ -3206,6 +3206,11 @@ bool x2Dtop, y2Dright, layer2Dtop; bool xySym, xyzSym, zSign, nearhoriz; +#if HAVE_FREETYPE + // freetype renderer, used for calculation of text (tick labels) size + ft_render text_renderer; +#endif + void set_text_child (handle_property& h, const std::string& who, const octave_value& v); @@ -3288,11 +3293,11 @@ radio_property cameraviewanglemode , "{auto}|manual" array_property currentpoint , Matrix (2, 3, 0.0) radio_property drawmode , "{normal}|fast" - radio_property fontangle , "{normal}|italic|oblique" - string_property fontname , OCTAVE_DEFAULT_FONTNAME - double_property fontsize , 10 + radio_property fontangle u , "{normal}|italic|oblique" + string_property fontname u , OCTAVE_DEFAULT_FONTNAME + double_property fontsize u , 10 radio_property fontunits SU , "{points}|normalized|inches|centimeters|pixels" - radio_property fontweight , "{normal}|light|demi|bold" + radio_property fontweight u , "{normal}|light|demi|bold" radio_property gridlinestyle , "-|--|{:}|-.|none" string_array_property linestyleorder , "-" double_property linewidth , 0.5 @@ -3318,6 +3323,8 @@ row_vector_property zmtick h , Matrix () // hidden properties for inset array_property looseinset hu , Matrix (1, 4, 0.0) + // hidden properties for alignment of subplots + radio_property autopos_tag h , "{none}|subplot" END_PROPERTIES protected: @@ -3411,7 +3418,15 @@ calc_ticklabels (ztick, zticklabel, zscale.is ("log")); } + void update_font (void); + void update_fontname (void) { update_font (); } + void update_fontsize (void) { update_font (); } + void update_fontangle (void) { update_font (); } + void update_fontweight (void) { update_font (); } + + void sync_positions (const Matrix& linset); void sync_positions (void); + void update_outerposition (void) { set_activepositionproperty ("outerposition"); @@ -3712,7 +3727,7 @@ Matrix get_extent_matrix (void) const; const uint8NDArray& get_pixels (void) const { return pixels; } #if HAVE_FREETYPE - // freetype render, used for text rendering + // freetype renderer, used for calculation of text size ft_render renderer; #endif @@ -3722,6 +3737,7 @@ position.add_constraint (dim_vector (1, 2)); position.add_constraint (dim_vector (1, 3)); cached_units = get_units (); + update_font (); } private: @@ -3757,13 +3773,14 @@ void update_horizontalalignmentmode (void) { request_autopos (); } void update_verticalalignmentmode (void) { request_autopos (); } + void update_font (void); void update_string (void) { request_autopos (); update_text_extent (); } void update_rotation (void) { update_text_extent (); } - void update_color (void) { update_text_extent (); } - void update_fontname (void) { update_text_extent (); } - void update_fontsize (void) { update_text_extent (); } - void update_fontangle (void) { update_text_extent (); } - void update_fontweight (void) { update_text_extent (); } + void update_color (void) { update_font (); } + void update_fontname (void) { update_font (); update_text_extent (); } + void update_fontsize (void) { update_font (); update_text_extent (); } + void update_fontangle (void) { update_font (); update_text_extent (); } + void update_fontweight (void) { update_font (); update_text_extent (); } void update_interpreter (void) { update_text_extent (); } void update_horizontalalignment (void) { update_text_extent (); } void update_verticalalignment (void) { update_text_extent (); }
--- a/src/help.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/help.cc Fri Aug 12 14:16:34 2011 -0400 @@ -749,6 +749,9 @@ const string_vector bif = symbol_table::built_in_function_names (); const int bif_len = bif.length (); + const string_vector cfl = symbol_table::cmdline_function_names (); + const int cfl_len = cfl.length (); + const string_vector lcl = symbol_table::variable_names (); const int lcl_len = lcl.length (); @@ -758,7 +761,8 @@ const string_vector afl = autoloaded_functions (); const int afl_len = afl.length (); - const int total_len = key_len + bif_len + lcl_len + ffl_len + afl_len; + const int total_len + = key_len + bif_len + cfl_len + lcl_len + ffl_len + afl_len; string_vector list (total_len); @@ -772,6 +776,9 @@ for (i = 0; i < bif_len; i++) list[j++] = bif[i]; + for (i = 0; i < cfl_len; i++) + list[j++] = cfl[i]; + for (i = 0; i < lcl_len; i++) list[j++] = lcl[i];
--- a/src/input.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/input.cc Fri Aug 12 14:16:34 2011 -0400 @@ -686,93 +686,88 @@ frame.protect_var (VPS1); VPS1 = prompt; - if (stdin_is_tty) + if (! (interactive || forced_interactive) + || (reading_fcn_file + || reading_classdef_file + || reading_script_file + || get_input_from_eval_string + || input_from_startup_file + || input_from_command_line_file)) { - if (! (interactive || forced_interactive) - || (reading_fcn_file - || reading_classdef_file - || reading_script_file - || get_input_from_eval_string - || input_from_startup_file - || input_from_command_line_file)) - { - frame.protect_var (forced_interactive); - forced_interactive = true; + frame.protect_var (forced_interactive); + forced_interactive = true; + + frame.protect_var (reading_fcn_file); + reading_fcn_file = false; + + frame.protect_var (reading_classdef_file); + reading_classdef_file = false; + + frame.protect_var (reading_script_file); + reading_script_file = false; - frame.protect_var (reading_fcn_file); - reading_fcn_file = false; + frame.protect_var (input_from_startup_file); + input_from_startup_file = false; + + frame.protect_var (input_from_command_line_file); + input_from_command_line_file = false; - frame.protect_var (reading_classdef_file); - reading_classdef_file = false; + frame.protect_var (get_input_from_eval_string); + get_input_from_eval_string = false; + + YY_BUFFER_STATE old_buf = current_buffer (); + YY_BUFFER_STATE new_buf = create_buffer (get_input_from_stdin ()); + + // FIXME: are these safe? + frame.add_fcn (switch_to_buffer, old_buf); + frame.add_fcn (delete_buffer, new_buf); - frame.protect_var (reading_script_file); - reading_script_file = false; + switch_to_buffer (new_buf); + } + + while (Vdebugging) + { + reset_error_handler (); + + reset_parser (); - frame.protect_var (input_from_startup_file); - input_from_startup_file = false; + // Save current value of global_command. + frame.protect_var (global_command); + + global_command = 0; - frame.protect_var (input_from_command_line_file); - input_from_command_line_file = false; + // Do this with an unwind-protect cleanup function so that the + // forced variables will be unmarked in the event of an interrupt. + symbol_table::scope_id scope = symbol_table::top_scope (); + frame.add_fcn (symbol_table::unmark_forced_variables, scope); - frame.protect_var (get_input_from_eval_string); - get_input_from_eval_string = false; + // This is the same as yyparse in parse.y. + int retval = octave_parse (); - YY_BUFFER_STATE old_buf = current_buffer (); - YY_BUFFER_STATE new_buf = create_buffer (get_input_from_stdin ()); + if (retval == 0 && global_command) + { + global_command->accept (*current_evaluator); - // FIXME: are these safe? - frame.add_fcn (switch_to_buffer, old_buf); - frame.add_fcn (delete_buffer, new_buf); + // FIXME -- To avoid a memory leak, global_command should be + // deleted, I think. But doing that here causes trouble if + // an error occurs while executing a debugging command + // (dbstep, for example). It's not clear to me why that + // happens. + // + // delete global_command; + // + // global_command = 0; - switch_to_buffer (new_buf); + if (octave_completion_matches_called) + octave_completion_matches_called = false; } - while (Vdebugging) - { - reset_error_handler (); - - reset_parser (); - - // Save current value of global_command. - frame.protect_var (global_command); - - global_command = 0; - - // Do this with an unwind-protect cleanup function so that the - // forced variables will be unmarked in the event of an interrupt. - symbol_table::scope_id scope = symbol_table::top_scope (); - frame.add_fcn (symbol_table::unmark_forced_variables, scope); - - // This is the same as yyparse in parse.y. - int retval = octave_parse (); - - if (retval == 0 && global_command) - { - global_command->accept (*current_evaluator); + // Unmark forced variables. + // Restore previous value of global_command. + frame.run_top (2); - // FIXME -- To avoid a memory leak, global_command should be - // deleted, I think. But doing that here causes trouble if - // an error occurs while executing a debugging command - // (dbstep, for example). It's not clear to me why that - // happens. - // - // delete global_command; - // - // global_command = 0; - - if (octave_completion_matches_called) - octave_completion_matches_called = false; - } - - // Unmark forced variables. - // Restore previous value of global_command. - frame.run_top (2); - - octave_quit (); - } + octave_quit (); } - else - warning ("invalid attempt to debug script read from stdin"); } // If the user simply hits return, this will produce an empty matrix.
--- a/src/lex.ll Fri Aug 12 14:05:48 2011 -0400 +++ b/src/lex.ll Fri Aug 12 14:16:34 2011 -0400 @@ -164,13 +164,13 @@ } \ while (0) -#define BIN_OP_RETURN(tok, convert, bos) \ +#define BIN_OP_RETURN_INTERNAL(tok, convert, bos, qit) \ do \ { \ yylval.tok_val = new token (input_line_number, current_input_column); \ token_stack.push (yylval.tok_val); \ current_input_column += yyleng; \ - lexer_flags.quote_is_transpose = false; \ + lexer_flags.quote_is_transpose = qit; \ lexer_flags.convert_spaces_to_comma = convert; \ lexer_flags.looking_for_object_index = false; \ lexer_flags.at_beginning_of_statement = bos; \ @@ -178,6 +178,21 @@ } \ while (0) +#define XBIN_OP_RETURN_INTERNAL(tok, convert, bos, qit) \ + do \ + { \ + gripe_matlab_incompatible_operator (yytext); \ + BIN_OP_RETURN_INTERNAL (tok, convert, bos, qit); \ + } \ + while (0) + +#define BIN_OP_RETURN(tok, convert, bos) \ + do \ + { \ + BIN_OP_RETURN_INTERNAL (tok, convert, bos, false); \ + } \ + while (0) + #define XBIN_OP_RETURN(tok, convert, bos) \ do \ { \ @@ -896,8 +911,8 @@ ".^" { LEXER_DEBUG (".^"); BIN_OP_RETURN (EPOW, false, false); } ".**" { LEXER_DEBUG (".**"); XBIN_OP_RETURN (EPOW, false, false); } ".'" { LEXER_DEBUG (".'"); do_comma_insert_check (); BIN_OP_RETURN (TRANSPOSE, true, false); } -"++" { LEXER_DEBUG ("++"); do_comma_insert_check (); XBIN_OP_RETURN (PLUS_PLUS, true, false); } -"--" { LEXER_DEBUG ("--"); do_comma_insert_check (); XBIN_OP_RETURN (MINUS_MINUS, true, false); } +"++" { LEXER_DEBUG ("++"); do_comma_insert_check (); XBIN_OP_RETURN_INTERNAL (PLUS_PLUS, true, false, true); } +"--" { LEXER_DEBUG ("--"); do_comma_insert_check (); XBIN_OP_RETURN_INTERNAL (MINUS_MINUS, true, false, true); } "<=" { LEXER_DEBUG ("<="); BIN_OP_RETURN (EXPR_LE, false, false); } "==" { LEXER_DEBUG ("=="); BIN_OP_RETURN (EXPR_EQ, false, false); } "~=" { LEXER_DEBUG ("~="); BIN_OP_RETURN (EXPR_NE, false, false); } @@ -3435,6 +3450,14 @@ return retval; } +/* + +%!assert (iskeyword ("for")) +%!assert (iskeyword ("fort"), false) +%!assert (iskeyword ("fft"), false) + +*/ + void prep_lexer_for_script_file (void) {
--- a/src/load-save.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/load-save.cc Fri Aug 12 14:16:34 2011 -0400 @@ -545,6 +545,9 @@ @deftypefnx {Command} {} load options file\n\ @deftypefnx {Command} {} load options file v1 v2 @dots{}\n\ @deftypefnx {Command} {S =} load (\"options\", \"file\", \"v1\", \"v2\", @dots{})\n\ +@deftypefnx {Command} {} load file options\n\ +@deftypefnx {Command} {} load file options v1 v2 @dots{}\n\ +@deftypefnx {Command} {S =} load (\"file\", \"options\", \"v1\", \"v2\", @dots{})\n\ Load the named variables @var{v1}, @var{v2}, @dots{}, from the file\n\ @var{file}. If no variables are specified then all variables found in the\n\ file will be loaded. As with @code{save}, the list of variables to extract\n\ @@ -642,6 +645,16 @@ if (error_state) return retval; + int i = 1; + std::string orig_fname = ""; + + // Function called with Matlab-style ["filename", options] syntax + if (argv[1].at(0) != '-') + { + orig_fname = argv[1]; + i++; + } + // It isn't necessary to have the default load format stored in a // user preference variable since we can determine the type of file // as we are reading. @@ -651,8 +664,7 @@ bool list_only = false; bool verbose = false; - int i; - for (i = 1; i < argc; i++) + for (i; i < argc; i++) { if (argv[i] == "-force" || argv[i] == "-f") { @@ -710,19 +722,24 @@ break; } - if (i == argc) + if (orig_fname == "") { - print_usage (); - return retval; + if (i == argc) + { + print_usage (); + return retval; + } + else + orig_fname = argv[i]; } - - std::string orig_fname = argv[i]; + else + i--; oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown; bool swap = false; - if (argv[i] == "-") + if (orig_fname == "-") { i++; @@ -747,7 +764,7 @@ } else { - std::string fname = file_ops::tilde_expand (argv[i]); + std::string fname = file_ops::tilde_expand (orig_fname); fname = find_file_to_load (fname, orig_fname);
--- a/src/ls-mat5.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ls-mat5.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1225,21 +1225,29 @@ else { octave_class* cls = new octave_class (m, classname); - cls->reconstruct_exemplar (); - - if (! cls->reconstruct_parents ()) - warning ("load: unable to reconstruct object inheritance"); - - tc = cls; - if (load_path::find_method (classname, "loadobj") != - std::string()) + + if (cls->reconstruct_exemplar ()) { - octave_value_list tmp = feval ("loadobj", tc, 1); - - if (! error_state) - tc = tmp(0); - else - goto data_read_error; + + if (! cls->reconstruct_parents ()) + warning ("load: unable to reconstruct object inheritance"); + + tc = cls; + if (load_path::find_method (classname, "loadobj") != + std::string()) + { + octave_value_list tmp = feval ("loadobj", tc, 1); + + if (! error_state) + tc = tmp(0); + else + goto data_read_error; + } + } + else + { + tc = m; + warning ("load: element has been converted to a structure"); } } }
--- a/src/oct-parse.yy Fri Aug 12 14:05:48 2011 -0400 +++ b/src/oct-parse.yy Fri Aug 12 14:16:34 2011 -0400 @@ -471,7 +471,7 @@ %type <tree_matrix_type> matrix_rows matrix_rows1 %type <tree_cell_type> cell_rows cell_rows1 %type <tree_expression_type> matrix cell -%type <tree_expression_type> primary_expr postfix_expr prefix_expr binary_expr +%type <tree_expression_type> primary_expr oper_expr %type <tree_expression_type> simple_expr colon_expr assign_expr expression %type <tree_identifier_type> identifier fcn_name magic_tilde %type <tree_identifier_type> superclass_identifier meta_identifier @@ -514,7 +514,6 @@ %type <dummy_type> class_body // Precedence and associativity. -%left ';' ',' '\n' %right '=' ADD_EQ SUB_EQ MUL_EQ DIV_EQ LEFTDIV_EQ POW_EQ EMUL_EQ EDIV_EQ ELEFTDIV_EQ EPOW_EQ OR_EQ AND_EQ LSHIFT_EQ RSHIFT_EQ %left EXPR_OR_OR %left EXPR_AND_AND @@ -525,8 +524,9 @@ %left ':' %left '-' '+' EPLUS EMINUS %left '*' '/' LEFTDIV EMUL EDIV ELEFTDIV -%left UNARY PLUS_PLUS MINUS_MINUS EXPR_NOT +%right UNARY EXPR_NOT %left POW EPOW QUOTE TRANSPOSE +%right PLUS_PLUS MINUS_MINUS %left '(' '.' '{' // Where to start. @@ -796,69 +796,61 @@ { lexer_flags.looking_at_indirect_ref = true; } ; -postfix_expr : primary_expr +oper_expr : primary_expr { $$ = $1; } - | postfix_expr '(' ')' + | oper_expr PLUS_PLUS + { $$ = make_postfix_op (PLUS_PLUS, $1, $2); } + | oper_expr MINUS_MINUS + { $$ = make_postfix_op (MINUS_MINUS, $1, $2); } + | oper_expr '(' ')' { $$ = make_index_expression ($1, 0, '('); } - | postfix_expr '(' arg_list ')' + | oper_expr '(' arg_list ')' { $$ = make_index_expression ($1, $3, '('); } - | postfix_expr '{' '}' + | oper_expr '{' '}' { $$ = make_index_expression ($1, 0, '{'); } - | postfix_expr '{' arg_list '}' + | oper_expr '{' arg_list '}' { $$ = make_index_expression ($1, $3, '{'); } - | postfix_expr PLUS_PLUS - { $$ = make_postfix_op (PLUS_PLUS, $1, $2); } - | postfix_expr MINUS_MINUS - { $$ = make_postfix_op (MINUS_MINUS, $1, $2); } - | postfix_expr QUOTE + | oper_expr QUOTE { $$ = make_postfix_op (QUOTE, $1, $2); } - | postfix_expr TRANSPOSE + | oper_expr TRANSPOSE { $$ = make_postfix_op (TRANSPOSE, $1, $2); } - | postfix_expr indirect_ref_op STRUCT_ELT + | oper_expr indirect_ref_op STRUCT_ELT { $$ = make_indirect_ref ($1, $3->text ()); } - | postfix_expr indirect_ref_op '(' expression ')' + | oper_expr indirect_ref_op '(' expression ')' { $$ = make_indirect_ref ($1, $4); } - ; - -prefix_expr : postfix_expr - { $$ = $1; } - | binary_expr - { $$ = $1; } - | PLUS_PLUS prefix_expr %prec UNARY + | PLUS_PLUS oper_expr %prec UNARY { $$ = make_prefix_op (PLUS_PLUS, $2, $1); } - | MINUS_MINUS prefix_expr %prec UNARY + | MINUS_MINUS oper_expr %prec UNARY { $$ = make_prefix_op (MINUS_MINUS, $2, $1); } - | EXPR_NOT prefix_expr %prec UNARY + | EXPR_NOT oper_expr %prec UNARY { $$ = make_prefix_op (EXPR_NOT, $2, $1); } - | '+' prefix_expr %prec UNARY + | '+' oper_expr %prec UNARY { $$ = make_prefix_op ('+', $2, $1); } - | '-' prefix_expr %prec UNARY + | '-' oper_expr %prec UNARY { $$ = make_prefix_op ('-', $2, $1); } - ; - -binary_expr : prefix_expr POW prefix_expr + | oper_expr POW oper_expr { $$ = make_binary_op (POW, $1, $2, $3); } - | prefix_expr EPOW prefix_expr + | oper_expr EPOW oper_expr { $$ = make_binary_op (EPOW, $1, $2, $3); } - | prefix_expr '+' prefix_expr + | oper_expr '+' oper_expr { $$ = make_binary_op ('+', $1, $2, $3); } - | prefix_expr '-' prefix_expr + | oper_expr '-' oper_expr { $$ = make_binary_op ('-', $1, $2, $3); } - | prefix_expr '*' prefix_expr + | oper_expr '*' oper_expr { $$ = make_binary_op ('*', $1, $2, $3); } - | prefix_expr '/' prefix_expr + | oper_expr '/' oper_expr { $$ = make_binary_op ('/', $1, $2, $3); } - | prefix_expr EPLUS prefix_expr + | oper_expr EPLUS oper_expr { $$ = make_binary_op ('+', $1, $2, $3); } - | prefix_expr EMINUS prefix_expr + | oper_expr EMINUS oper_expr { $$ = make_binary_op ('-', $1, $2, $3); } - | prefix_expr EMUL prefix_expr + | oper_expr EMUL oper_expr { $$ = make_binary_op (EMUL, $1, $2, $3); } - | prefix_expr EDIV prefix_expr + | oper_expr EDIV oper_expr { $$ = make_binary_op (EDIV, $1, $2, $3); } - | prefix_expr LEFTDIV prefix_expr + | oper_expr LEFTDIV oper_expr { $$ = make_binary_op (LEFTDIV, $1, $2, $3); } - | prefix_expr ELEFTDIV prefix_expr + | oper_expr ELEFTDIV oper_expr { $$ = make_binary_op (ELEFTDIV, $1, $2, $3); } ; @@ -866,9 +858,9 @@ { $$ = finish_colon_expression ($1); } ; -colon_expr1 : prefix_expr +colon_expr1 : oper_expr { $$ = new tree_colon_expression ($1); } - | colon_expr1 ':' prefix_expr + | colon_expr1 ':' oper_expr { if (! ($$ = $1->append ($3))) ABORT_PARSE; @@ -2908,6 +2900,7 @@ } fcn->stash_function_name (id_name); + fcn->stash_fcn_location (input_line_number, current_input_column); if (! help_buf.empty () && current_function_depth == 1 && ! parsing_subfunctions) @@ -3348,11 +3341,10 @@ break; case '\n': - current_input_column = 0; + current_input_column = 1; break; default: - current_input_column--; reader.ungetc (c); goto done; }
--- a/src/oct-stream.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/oct-stream.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1227,151 +1227,9 @@ if (c1 != EOF) { - if (c1 == 'N') - { - int c2 = is.get (); - - if (c2 != EOF) - { - if (c2 == 'A') - { - int c3 = is.get (); - - if (c3 != EOF) - { - is.putback (c3); - - if (isspace (c3) || ispunct (c3)) - ref = octave_NA; - else - { - is.putback (c2); - is.putback (c1); - - is >> ref; - } - } - else - { - is.clear (); - - ref = octave_NA; - } - } - else if (c2 == 'a') - { - int c3 = is.get (); - - if (c3 != EOF) - { - if (c3 == 'N') - { - int c4 = is.get (); - - if (c4 != EOF) - { - is.putback (c4); - - if (isspace (c4) || ispunct (c4)) - ref = octave_NaN; - else - { - is.putback (c3); - is.putback (c2); - is.putback (c1); - - is >> ref; - } - } - else - { - is.clear (); - - ref = octave_NaN; - } - } - else - { - is.putback (c3); - is.putback (c2); - is.putback (c1); - - is >> ref; - } - } - } - else - { - is.putback (c2); - is.putback (c1); - - is >> ref; - } - } - } - else if (c1 == 'I') - { - int c2 = is.get (); - - if (c2 != EOF) - { - if (c2 == 'n') - { - int c3 = is.get (); - - if (c3 != EOF) - { - if (c3 == 'f') - { - int c4 = is.get (); - - if (c4 != EOF) - { - is.putback (c4); - - if (isspace (c4) || ispunct (c4)) - ref = octave_Inf; - else - { - is.putback (c3); - is.putback (c2); - is.putback (c1); - - is >> ref; - } - } - else - { - is.clear (); - - ref = octave_Inf; - } - } - else - { - is.putback (c3); - is.putback (c2); - is.putback (c1); - - is >> ref; - } - } - else - { - is.putback (c2); - is.putback (c1); - - is >> ref; - } - } - } - } - else - { - is.putback (c1); - - is >> ref; - } + is.putback (c1); + + ref = octave_read_value<double> (is); } } break; @@ -3014,6 +2872,15 @@ { long eof_pos = rep->tell (); + if (origin == SEEK_CUR) + { + // Move back to original position, otherwise we will be + // seeking from the end of file which is probably not the + // original location. + + rep->seek (orig_pos, SEEK_SET); + } + // Attempt to move to desired position; may be outside bounds // of existing file. @@ -3025,8 +2892,8 @@ long desired_pos = rep->tell (); - // I don't think desired_pos can be less than zero, but - // we'll check anyway... + // I don't think save_pos can be less than zero, but we'll + // check anyway... if (desired_pos > eof_pos || desired_pos < 0) {
--- a/src/octave.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/octave.cc Fri Aug 12 14:16:34 2011 -0400 @@ -971,6 +971,11 @@ return retval; } +/* +%!error argv (1); +%!assert (iscellstr (argv ())); +*/ + DEFUN (program_invocation_name, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} program_invocation_name ()\n\ @@ -993,6 +998,11 @@ return retval; } +/* +%!error program_invocation_name (1); +%!assert (ischar (program_invocation_name ())); +*/ + DEFUN (program_name, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} program_name ()\n\ @@ -1010,3 +1020,8 @@ return retval; } + +/* +%!error program_name (1); +%!assert (ischar (program_name ())); +*/
--- a/src/ov-base.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-base.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1548,3 +1548,16 @@ { return SET_INTERNAL_VARIABLE (sparse_auto_mutate); } + +/* + +%!test + s = speye(3); + sparse_auto_mutate (false); + s(:, 1) = 1; + assert (typeinfo (s), "sparse matrix"); + sparse_auto_mutate (true); + s(1, :) = 1; + assert (typeinfo (s), "matrix"); + +*/
--- a/src/ov-builtin.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-builtin.cc Fri Aug 12 14:16:34 2011 -0400 @@ -29,6 +29,7 @@ #include "oct-obj.h" #include "ov-builtin.h" #include "ov.h" +#include "profiler.h" #include "toplev.h" #include "unwind-prot.h" @@ -125,6 +126,8 @@ try { + profile_data_accumulator::enter pe (profiler, profiler_name ()); + retval = (*f) (args, nargout); // Do not allow null values to be returned from functions. // FIXME -- perhaps true builtins should be allowed?
--- a/src/ov-fcn.h Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-fcn.h Fri Aug 12 14:16:34 2011 -0400 @@ -60,6 +60,9 @@ virtual bool is_system_fcn_file (void) const { return false; } virtual std::string fcn_file_name (void) const { return std::string (); } + + // The name to show in the profiler (also used as map-key). + virtual std::string profiler_name (void) const { return name (); } virtual std::string parent_fcn_name (void) const { return std::string (); }
--- a/src/ov-flt-re-mat.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-flt-re-mat.cc Fri Aug 12 14:16:34 2011 -0400 @@ -839,3 +839,32 @@ return octave_value (); } + +/* + +%!assert (class (single(1)), "single") +%!assert (class (single(1 + i)), "single") +%!assert (class (single (int8 (1))), "single") +%!assert (class (single (uint8 (1))), "single") +%!assert (class (single (int16 (1))), "single") +%!assert (class (single (uint16 (1))), "single") +%!assert (class (single (int32 (1))), "single") +%!assert (class (single (uint32 (1))), "single") +%!assert (class (single (int64 (1))), "single") +%!assert (class (single (uint64 (1))), "single") +%!assert (class (single (true)), "single") +%!assert (class (single ("A")), "single") +%!error (single (sparse (1))) +%!test +%! x = diag ([1 3 2]); +%! y = single (x); +%! assert (class (x), "double"); +%! assert (class (y), "single"); +%!test +%! x = diag ([i 3 2]); +%! y = single (x); +%! assert (class (x), "double"); +%! assert (class (y), "single"); + +*/ +
--- a/src/ov-int16.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-int16.cc Fri Aug 12 14:16:34 2011 -0400 @@ -82,3 +82,15 @@ { OCTAVE_TYPE_CONV_BODY (int16); } + +/* + +%!assert (class (int16 (1)), "int16") +%!assert (int16 (1.25), int16 (1)) +%!assert (int16 (1.5), int16 (2)) +%!assert (int16 (-1.5), int16 (-2)) +%!assert (int16 (2^17), int16 (2^16-1)) +%!assert (int16 (-2^17), int16 (-2^16)) + +*/ +
--- a/src/ov-int32.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-int32.cc Fri Aug 12 14:16:34 2011 -0400 @@ -82,3 +82,15 @@ { OCTAVE_TYPE_CONV_BODY (int32); } + +/* + +%!assert (class (int32 (1)), "int32") +%!assert (int32 (1.25), int32 (1)) +%!assert (int32 (1.5), int32 (2)) +%!assert (int32 (-1.5), int32 (-2)) +%!assert (int32 (2^33), int32 (2^32-1)) +%!assert (int32 (-2^33), int32 (-2^32)) + +*/ +
--- a/src/ov-int64.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-int64.cc Fri Aug 12 14:16:34 2011 -0400 @@ -82,3 +82,15 @@ { OCTAVE_TYPE_CONV_BODY (int64); } + +/* + +%!assert (class (int64 (1)), "int64") +%!assert (int64 (1.25), int64 (1)) +%!assert (int64 (1.5), int64 (2)) +%!assert (int64 (-1.5), int64 (-2)) +%!assert (int64 (2^65), int64 (2^64-1)) +%!assert (int64 (-2^65), int64 (-2^64)) + +*/ +
--- a/src/ov-int8.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-int8.cc Fri Aug 12 14:16:34 2011 -0400 @@ -82,3 +82,14 @@ { OCTAVE_TYPE_CONV_BODY (int8); } + +/* + +%!assert (class (int8 (1)), "int8") +%!assert (int8 (1.25), int8 (1)) +%!assert (int8 (1.5), int8 (2)) +%!assert (int8 (-1.5), int8 (-2)) +%!assert (int8 (2^9), int8 (2^8-1)) +%!assert (int8 (-2^9), int8 (-2^8)) + +*/
--- a/src/ov-mex-fcn.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-mex-fcn.cc Fri Aug 12 14:16:34 2011 -0400 @@ -33,6 +33,7 @@ #include "oct-obj.h" #include "ov-mex-fcn.h" #include "ov.h" +#include "profiler.h" #include "toplev.h" #include "unwind-prot.h" @@ -147,6 +148,7 @@ try { + profile_data_accumulator::enter pe (profiler, profiler_name ()); retval = call_mex (have_fmex, mex_fcn_ptr, args, nargout, this); } catch (octave_execution_exception)
--- a/src/ov-null-mat.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-null-mat.cc Fri Aug 12 14:16:34 2011 -0400 @@ -118,3 +118,17 @@ return retval; } +/* + +%!assert (isnull ([]), true) +%!assert (isnull ([1]), false) +%!assert (isnull (zeros (0,3)), false) +%!assert (isnull (""), true) +%!assert (isnull ("A"), false) +%!assert (isnull (''), true) +%!assert (isnull ('A'), false) +%!test +%! x = []; +%! assert (isnull (x), false); + +*/
--- a/src/ov-range.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-range.cc Fri Aug 12 14:16:34 2011 -0400 @@ -655,3 +655,16 @@ { return SET_INTERNAL_VARIABLE (allow_noninteger_range_as_index); } + +/* +%!test +%! x = 0:10; +%! save = allow_noninteger_range_as_index (0); +%! fail ('x(2.1:5)'); +%! assert (x(2:5), 1:4); +%! allow_noninteger_range_as_index (1); +%! assert (x(2.49:5), 1:3); +%! assert (x(2.5:5), 2:4); +%! assert (x(2.51:5), 2:4); +%! allow_noninteger_range_as_index (save); +*/
--- a/src/ov-re-mat.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-re-mat.cc Fri Aug 12 14:16:34 2011 -0400 @@ -979,3 +979,36 @@ return octave_value (); } + +/* + +%!assert (class (double (single (1))), "double") +%!assert (class (double (single (1 + i))), "double") +%!assert (class (double (int8 (1))), "double") +%!assert (class (double (uint8 (1))), "double") +%!assert (class (double (int16 (1))), "double") +%!assert (class (double (uint16 (1))), "double") +%!assert (class (double (int32 (1))), "double") +%!assert (class (double (uint32 (1))), "double") +%!assert (class (double (int64 (1))), "double") +%!assert (class (double (uint64 (1))), "double") +%!assert (class (double (true)), "double") +%!assert (class (double ("A")), "double") +%!test +%! x = sparse (logical ([1 0; 0 1])); +%! y = double (x); +%! assert (class (x), "logical"); +%! assert (class (y), "double"); +%! assert (issparse (y)); +%!test +%! x = diag (single ([1 3 2])); +%! y = double (x); +%! assert (class (x), "single"); +%! assert (class (y), "double"); +%!test +%! x = diag (single ([i 3 2])); +%! y = double (x); +%! assert (class (x), "single"); +%! assert (class (y), "double"); + +*/
--- a/src/ov-uint16.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-uint16.cc Fri Aug 12 14:16:34 2011 -0400 @@ -82,3 +82,15 @@ { OCTAVE_TYPE_CONV_BODY (uint16); } + +/* + +%!assert (class (uint16 (1)), "uint16") +%!assert (uint16 (1.25), uint16 (1)) +%!assert (uint16 (1.5), uint16 (2)) +%!assert (uint16 (-1.5), uint16 (0)) +%!assert (uint16 (2^17), uint16 (2^16-1)) +%!assert (uint16 (-2^17), uint16 (0)) + +*/ +
--- a/src/ov-uint32.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-uint32.cc Fri Aug 12 14:16:34 2011 -0400 @@ -82,3 +82,14 @@ { OCTAVE_TYPE_CONV_BODY (uint32); } + +/* + +%!assert (class (uint32 (1)), "uint32") +%!assert (uint32 (1.25), uint32 (1)) +%!assert (uint32 (1.5), uint32 (2)) +%!assert (uint32 (-1.5), uint32 (0)) +%!assert (uint32 (2^33), uint32 (2^32-1)) +%!assert (uint32 (-2^33), uint32 (0)) + +*/
--- a/src/ov-uint64.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-uint64.cc Fri Aug 12 14:16:34 2011 -0400 @@ -82,3 +82,14 @@ { OCTAVE_TYPE_CONV_BODY (uint64); } + +/* + +%!assert (class (uint64 (1)), "uint64") +%!assert (uint64 (1.25), uint64 (1)) +%!assert (uint64 (1.5), uint64 (2)) +%!assert (uint64 (-1.5), uint64 (0)) +%!assert (uint64 (2^65), uint64 (2^64-1)) +%!assert (uint64 (-2^65), uint64 (0)) + +*/
--- a/src/ov-uint8.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-uint8.cc Fri Aug 12 14:16:34 2011 -0400 @@ -82,3 +82,14 @@ { OCTAVE_TYPE_CONV_BODY (uint8); } + +/* + +%!assert (class (uint8 (1)), "uint8") +%!assert (uint8 (1.25), uint8 (1)) +%!assert (uint8 (1.5), uint8 (2)) +%!assert (uint8 (-1.5), uint8 (0)) +%!assert (uint8 (2^9), uint8 (2^8-1)) +%!assert (uint8 (-2^9), uint8 (0)) + +*/
--- a/src/ov-usr-fcn.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-usr-fcn.cc Fri Aug 12 14:16:34 2011 -0400 @@ -24,6 +24,8 @@ #include <config.h> #endif +#include <sstream> + #include "str-vec.h" #include <defaults.h> @@ -47,6 +49,7 @@ #include "unwind-prot.h" #include "utils.h" #include "parse.h" +#include "profiler.h" #include "variables.h" // Whether to optimize subsasgn method calls. @@ -131,7 +134,11 @@ frame.protect_var (tree_evaluator::statement_context); tree_evaluator::statement_context = tree_evaluator::script; - cmd_list->accept (*current_evaluator); + { + profile_data_accumulator::enter pe (profiler, + profiler_name ()); + cmd_list->accept (*current_evaluator); + } if (tree_return_command::returning) tree_return_command::returning = 0; @@ -176,6 +183,7 @@ : octave_user_code (std::string (), std::string ()), param_list (pl), ret_list (rl), cmd_list (cl), lead_comm (), trail_comm (), file_name (), + location_line (0), location_column (0), parent_name (), t_parsed (static_cast<time_t> (0)), t_checked (static_cast<time_t> (0)), system_fcn_file (false), call_depth (-1), @@ -217,6 +225,22 @@ file_name = nm; } +std::string +octave_user_function::profiler_name (void) const +{ + std::ostringstream result; + + if (is_inline_function ()) + result << "anonymous@" << fcn_file_name () + << ":" << location_line << ":" << location_column; + else if (is_subfunction ()) + result << parent_fcn_name () << ">" << name (); + else + result << name (); + + return result.str (); +} + void octave_user_function::mark_as_system_fcn_file (void) { @@ -431,22 +455,26 @@ bool special_expr = (is_inline_function () || cmd_list->is_anon_function_body ()); - if (special_expr) - { - assert (cmd_list->length () == 1); + { + profile_data_accumulator::enter pe (profiler, profiler_name ()); - tree_statement *stmt = 0; + if (special_expr) + { + assert (cmd_list->length () == 1); + + tree_statement *stmt = 0; - if ((stmt = cmd_list->front ()) - && stmt->is_expression ()) - { - tree_expression *expr = stmt->expression (); + if ((stmt = cmd_list->front ()) + && stmt->is_expression ()) + { + tree_expression *expr = stmt->expression (); - retval = expr->rvalue (nargout); - } - } - else - cmd_list->accept (*current_evaluator); + retval = expr->rvalue (nargout); + } + } + else + cmd_list->accept (*current_evaluator); + } if (echo_commands) print_code_function_trailer ();
--- a/src/ov-usr-fcn.h Fri Aug 12 14:05:48 2011 -0400 +++ b/src/ov-usr-fcn.h Fri Aug 12 14:16:34 2011 -0400 @@ -189,6 +189,12 @@ void stash_fcn_file_name (const std::string& nm); + void stash_fcn_location (int line, int col) + { + location_line = line; + location_column = col; + } + void stash_parent_fcn_name (const std::string& p) { parent_name = p; } void stash_parent_fcn_scope (symbol_table::scope_id ps) { parent_scope = ps; } @@ -207,6 +213,8 @@ std::string fcn_file_name (void) const { return file_name; } + std::string profiler_name (void) const; + std::string parent_fcn_name (void) const { return parent_name; } symbol_table::scope_id parent_fcn_scope (void) const { return parent_scope; } @@ -344,6 +352,10 @@ // The name of the file we parsed. std::string file_name; + // Location where this function was defined. + int location_line; + int location_column; + // The name of the parent function, if any. std::string parent_name;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/profiler.cc Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,416 @@ +/* + +Copyright (C) 2011 Daniel Kraft + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <cstddef> +#include <iostream> + +#include "defun.h" +#include "oct-time.h" +#include "ov-struct.h" +#include "pager.h" +#include "profiler.h" + +profile_data_accumulator::enter::enter (profile_data_accumulator& a, + const std::string& f) + : acc (a) +{ + if (acc.is_active ()) + { + fcn = f; + acc.enter_function (fcn); + } + else + fcn = ""; +} + +profile_data_accumulator::enter::~enter () +{ + if (fcn != "") + acc.exit_function (fcn); +} + +profile_data_accumulator::stats::stats () + : time (0.0), calls (0), recursive (false), + parents (), children () +{} + +octave_value +profile_data_accumulator::stats::function_set_value (const function_set& list) +{ + const octave_idx_type n = list.size (); + + RowVector retval (n); + octave_idx_type i = 0; + for (function_set::const_iterator p = list.begin (); p != list.end (); ++p) + { + retval(i) = *p; + ++i; + } + assert (i == n); + + return retval; +} + +profile_data_accumulator::tree_node::tree_node (tree_node* p, octave_idx_type f) + : parent (p), fcn_id (f), children (), time (0.0), calls (0) +{} + +profile_data_accumulator::tree_node::~tree_node () +{ + for (child_map::iterator i = children.begin (); i != children.end (); ++i) + delete i->second; +} + +profile_data_accumulator::tree_node* +profile_data_accumulator::tree_node::enter (octave_idx_type fcn) +{ + tree_node* retval; + + child_map::iterator pos = children.find (fcn); + if (pos == children.end ()) + { + retval = new tree_node (this, fcn); + children[fcn] = retval; + } + else + retval = pos->second; + + ++retval->calls; + return retval; +} + +profile_data_accumulator::tree_node* +profile_data_accumulator::tree_node::exit (octave_idx_type fcn) +{ + assert (parent); + assert (fcn_id == fcn); + + return parent; +} + +void +profile_data_accumulator::tree_node::build_flat (flat_profile& data) const +{ + // If this is not the top-level node, update profile entry for this function. + if (fcn_id != 0) + { + stats& entry = data[fcn_id - 1]; + + entry.time += time; + entry.calls += calls; + + assert (parent); + if (parent->fcn_id != 0) + { + entry.parents.insert (parent->fcn_id); + data[parent->fcn_id - 1].children.insert (fcn_id); + } + + if (!entry.recursive) + for (const tree_node* i = parent; i; i = i->parent) + if (i->fcn_id == fcn_id) + { + entry.recursive = true; + break; + } + } + + // Recurse on children. + for (child_map::const_iterator i = children.begin (); + i != children.end (); ++i) + i->second->build_flat (data); +} + +octave_value +profile_data_accumulator::tree_node::get_hierarchical (void) const +{ + /* Note that we don't generate the entry just for this node, but rather + a struct-array with entries for all children. This way, the top-node + (for which we don't want a real entry) generates already the final + hierarchical profile data. */ + + const octave_idx_type n = children.size (); + + Cell rv_indices (n, 1); + Cell rv_times (n, 1); + Cell rv_calls (n, 1); + Cell rv_children (n, 1); + + octave_idx_type i = 0; + for (child_map::const_iterator p = children.begin (); + p != children.end (); ++p) + { + const tree_node& entry = *p->second; + + rv_indices(i) = octave_value (p->first); + rv_times(i) = octave_value (entry.time); + rv_calls(i) = octave_value (entry.calls); + rv_children(i) = entry.get_hierarchical (); + + ++i; + } + assert (i == n); + + Octave_map retval; + + retval.assign ("Index", rv_indices); + retval.assign ("SelfTime", rv_times); + retval.assign ("NumCalls", rv_calls); + retval.assign ("Children", rv_children); + + return retval; +} + +profile_data_accumulator::profile_data_accumulator () + : known_functions (), fcn_index (), + enabled (false), call_tree (NULL), last_time (-1.0) +{} + +profile_data_accumulator::~profile_data_accumulator () +{ + if (call_tree) + delete call_tree; +} + +void +profile_data_accumulator::set_active (bool value) +{ + if (value) + { + // Create a call-tree top-node if there isn't yet one. + if (!call_tree) + call_tree = new tree_node (NULL, 0); + + // Let the top-node be the active one. This ensures we have a clean + // fresh start collecting times. + active_fcn = call_tree; + } + else + { + // Make sure we start with fresh timing if we're re-enabled later. + last_time = -1.0; + } + + enabled = value; +} + +void +profile_data_accumulator::enter_function (const std::string& fcn) +{ + // The enter class will check and only call us if the profiler is active. + assert (is_active ()); + assert (call_tree); + + // If there is already an active function, add to its time before + // pushing the new one. + if (active_fcn != call_tree) + add_current_time (); + + // Map the function's name to its index. + octave_idx_type fcn_idx; + fcn_index_map::iterator pos = fcn_index.find (fcn); + if (pos == fcn_index.end ()) + { + known_functions.push_back (fcn); + fcn_idx = known_functions.size (); + fcn_index[fcn] = fcn_idx; + } + else + fcn_idx = pos->second; + + active_fcn = active_fcn->enter (fcn_idx); + last_time = query_time (); +} + +void +profile_data_accumulator::exit_function (const std::string& fcn) +{ + assert (call_tree); + assert (active_fcn != call_tree); + + // Usually, if we are disabled this function is not even called. But the + // call disabling the profiler is an exception. So also check here + // and only record the time if enabled. + if (is_active ()) + add_current_time (); + + fcn_index_map::iterator pos = fcn_index.find (fcn); + assert (pos != fcn_index.end ()); + active_fcn = active_fcn->exit (pos->second); + + // If this was an "inner call", we resume executing the parent function + // up the stack. So note the start-time for this! + last_time = query_time (); +} + +void +profile_data_accumulator::reset (void) +{ + if (is_active ()) + { + error ("Can't reset active profiler."); + return; + } + + known_functions.clear (); + fcn_index.clear (); + + if (call_tree) + { + delete call_tree; + call_tree = NULL; + } + + last_time = -1.0; +} + +octave_value +profile_data_accumulator::get_flat (void) const +{ + const octave_idx_type n = known_functions.size (); + + flat_profile flat (n); + assert (call_tree); + call_tree->build_flat (flat); + + Cell rv_names (n, 1); + Cell rv_times (n, 1); + Cell rv_calls (n, 1); + Cell rv_recursive (n, 1); + Cell rv_parents (n, 1); + Cell rv_children (n, 1); + + for (octave_idx_type i = 0; i != n; ++i) + { + rv_names(i) = octave_value (known_functions[i]); + rv_times(i) = octave_value (flat[i].time); + rv_calls(i) = octave_value (flat[i].calls); + rv_recursive(i) = octave_value (flat[i].recursive); + rv_parents(i) = stats::function_set_value (flat[i].parents); + rv_children(i) = stats::function_set_value (flat[i].children); + } + + Octave_map retval; + + retval.assign ("FunctionName", rv_names); + retval.assign ("TotalTime", rv_times); + retval.assign ("NumCalls", rv_calls); + retval.assign ("IsRecursive", rv_recursive); + retval.assign ("Parents", rv_parents); + retval.assign ("Children", rv_children); + + return retval; +} + +octave_value +profile_data_accumulator::get_hierarchical (void) const +{ + assert (call_tree); + return call_tree->get_hierarchical (); +} + +double +profile_data_accumulator::query_time (void) const +{ + octave_time now; + return now.double_value (); +} + +void +profile_data_accumulator::add_current_time (void) +{ + const double t = query_time (); + assert (last_time >= 0.0 && last_time <= t); + + assert (call_tree && active_fcn != call_tree); + active_fcn->add_time (t - last_time); +} + +profile_data_accumulator profiler; + +// Enable or disable the profiler data collection. +DEFUN (__profiler_enable__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Function File} __profiler_enable ()\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value_list retval; + + const int nargin = args.length (); + if (nargin > 0) + { + if (nargin > 1) + { + print_usage (); + return retval; + } + + profiler.set_active (args(0).bool_value ()); + } + + retval(0) = profiler.is_active (); + + return retval; +} + +// Clear all collected profiling data. +DEFUN (__profiler_reset__, args, , + "-*- texinfo -*-\n\ +@deftypefn {Function File} __profiler_reset ()\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value_list retval; + const int nargin = args.length (); + + if (nargin > 0) + warning ("profiler_reset: ignoring extra arguments"); + + profiler.reset (); + + return retval; +} + +// Query the timings collected by the profiler. +DEFUN (__profiler_data__, args, nargout, + "-*- texinfo -*-\n\ +@deftypefn {Function File} __profiler_data ()\n\ +Undocumented internal function.\n\ +@end deftypefn") +{ + octave_value_list retval; + const int nargin = args.length (); + + if (nargin > 0) + warning ("profiler_data: ignoring extra arguments"); + + retval(0) = profiler.get_flat (); + if (nargout > 1) + retval(1) = profiler.get_hierarchical (); + + return retval; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/profiler.h Fri Aug 12 14:16:34 2011 -0400 @@ -0,0 +1,178 @@ +/* + +Copyright (C) 2011 Daniel Kraft + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +<http://www.gnu.org/licenses/>. + +*/ + +#if !defined (octave_profiler_h) +#define octave_profiler_h 1 + +#include <map> +#include <set> +#include <string> +#include <vector> + +class octave_value; + +class +OCTAVE_API +profile_data_accumulator +{ +public: + + // This is a utility class that can be used to call the enter/exit + // functions in a manner protected from stack unwinding. + class enter + { + private: + + profile_data_accumulator& acc; + std::string fcn; + + public: + + enter (profile_data_accumulator&, const std::string&); + virtual ~enter (void); + + private: + + // No copying! + enter (const enter&); + enter& operator = (const enter&); + }; + + profile_data_accumulator (void); + virtual ~profile_data_accumulator (); + + bool is_active (void) const { return enabled; } + void set_active (bool); + + void reset (void); + + octave_value get_flat (void) const; + octave_value get_hierarchical (void) const; + +private: + + // One entry in the flat profile (i.e., a collection of data for a single + // function). This is filled in when building the flat profile from the + // hierarchical call tree. + struct stats + { + stats (); + + double time; + unsigned calls; + + bool recursive; + + typedef std::set<octave_idx_type> function_set; + function_set parents; + function_set children; + + // Convert a function_set list to an Octave array of indices. + static octave_value function_set_value (const function_set&); + }; + + typedef std::vector<stats> flat_profile; + + // Store data for one node in the call-tree of the hierarchical profiler + // data we collect. + class tree_node + { + public: + + tree_node (tree_node*, octave_idx_type); + virtual ~tree_node (); + + void add_time (double dt) { time += dt; } + + // Enter a child function. It is created in the list of children if it + // wasn't already there. The now-active child node is returned. + tree_node* enter (octave_idx_type); + + // Exit function. As a sanity-check, it is verified that the currently + // active function actually is the one handed in here. Returned is the + // then-active node, which is our parent. + tree_node* exit (octave_idx_type); + + void build_flat (flat_profile&) const; + octave_value get_hierarchical (void) const; + + private: + + tree_node* parent; + octave_idx_type fcn_id; + + typedef std::map<octave_idx_type, tree_node*> child_map; + child_map children; + + // This is only time spent *directly* on this level, excluding children! + double time; + + unsigned calls; + + // No copying! + tree_node (const tree_node&); + tree_node& operator = (const tree_node&); + }; + + // Each function we see in the profiler is given a unique index (which + // simply counts starting from 1). We thus have to map profiler-names to + // those indices. For all other stuff, we identify functions by their index. + + typedef std::vector<std::string> function_set; + typedef std::map<std::string, octave_idx_type> fcn_index_map; + + function_set known_functions; + fcn_index_map fcn_index; + + bool enabled; + + tree_node* call_tree; + tree_node* active_fcn; + + // Store last timestamp we had, when the currently active function was called. + double last_time; + + // These are private as only the unwind-protecting inner class enter + // should be allowed to call them. + void enter_function (const std::string&); + void exit_function (const std::string&); + + // Query a timestamp, used for timing calls (obviously). + // This is not static because in the future, maybe we want a flag + // in the profiler or something to choose between cputime, wall-time, + // user-time, system-time, ... + double query_time () const; + + // Add the time elapsed since last_time to the function we're currently in. + // This is called from two different positions, thus it is useful to have + // it as a seperate function. + void add_current_time (void); + + // No copying! + profile_data_accumulator (const profile_data_accumulator&); + profile_data_accumulator& operator = (const profile_data_accumulator&); +}; + +// The instance used. +extern profile_data_accumulator profiler; + +#endif
--- a/src/pt-binop.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/pt-binop.cc Fri Aug 12 14:16:34 2011 -0400 @@ -28,6 +28,7 @@ #include "defun.h" #include "oct-obj.h" #include "ov.h" +#include "profiler.h" #include "pt-binop.h" #include "pt-bp.h" #include "pt-walk.h" @@ -120,6 +121,15 @@ if (! error_state && b.is_defined ()) { + profile_data_accumulator::enter pe (profiler, + "binary " + oper ()); + + // Note: The profiler does not catch the braindead + // short-circuit evaluation code above, but that should be + // ok. The evaluation of operands and the operator itself + // is entangled and it's not clear where to start/stop + // timing the operator to make it reasonable. + retval = ::do_binary_op (etype, a, b); if (error_state) @@ -183,6 +193,11 @@ bool result = false; + // This evaluation is not caught by the profiler, since we can't find + // a reasonable place where to time. Note that we don't want to + // include evaluation of LHS or RHS into the timing, but this is + // entangled together with short-circuit evaluation here. + if (op_lhs) { octave_value a = op_lhs->rvalue1 (); @@ -279,3 +294,19 @@ { return SET_INTERNAL_VARIABLE (do_braindead_shortcircuit_evaluation); } + +/* + +%!test +%! x = 0; +%! do_braindead_shortcircuit_evaluation (0); +%! if (1 | (x = 1)) +%! endif +%! assert (x, 1); +%! do_braindead_shortcircuit_evaluation (1); +%! if (1 | (x = 0)) +%! endif +%! assert (x, 1); + +*/ +
--- a/src/pt-eval.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/pt-eval.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1202,6 +1202,17 @@ return SET_INTERNAL_VARIABLE (max_recursion_depth); } +/* +%!error (max_recursion_depth (1, 2)); +%!test +%! orig_val = max_recursion_depth (); +%! old_val = max_recursion_depth (2*orig_val); +%! assert (orig_val, old_val); +%! assert (max_recursion_depth (), 2*orig_val); +%! max_recursion_depth (orig_val); +%! assert (max_recursion_depth (), orig_val); +*/ + DEFUN (silent_functions, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} silent_functions ()\n\ @@ -1214,3 +1225,14 @@ { return SET_INTERNAL_VARIABLE (silent_functions); } + +/* +%!error (silent_functions (1, 2)); +%!test +%! orig_val = silent_functions (); +%! old_val = silent_functions (! orig_val); +%! assert (orig_val, old_val); +%! assert (silent_functions (), ! orig_val); +%! silent_functions (orig_val); +%! assert (silent_functions (), orig_val); +*/
--- a/src/pt-fcn-handle.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/pt-fcn-handle.cc Fri Aug 12 14:16:34 2011 -0400 @@ -127,6 +127,7 @@ } uf->mark_as_inline_function (); + uf->stash_fcn_location (line (), column ()); octave_value ov_fcn (uf);
--- a/src/pt-mat.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/pt-mat.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1146,3 +1146,18 @@ { return SET_INTERNAL_VARIABLE (string_fill_char); } + +/* +%!error (string_fill_char (1, 2)); +%% string_fill_char() function call must be outside of %!test block +%% due to the way a %!test block is wrapped inside a function +%!shared orig_val, old_val +%! orig_val = string_fill_char (); +%! old_val = string_fill_char ("X"); +%!test +%! assert (orig_val, old_val); +%! assert (string_fill_char (), "X"); +%! assert (["these"; "are"; "strings"], ["theseXX"; "areXXXX"; "strings"]); +%! string_fill_char (orig_val); +%! assert (string_fill_char (), orig_val); +*/
--- a/src/pt-unop.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/pt-unop.cc Fri Aug 12 14:16:34 2011 -0400 @@ -28,6 +28,7 @@ #include "oct-obj.h" #include "oct-lvalue.h" #include "ov.h" +#include "profiler.h" #include "pt-bp.h" #include "pt-unop.h" #include "pt-walk.h" @@ -72,6 +73,9 @@ if (! error_state) { + profile_data_accumulator::enter pe (profiler, + "prefix " + oper ()); + ref.do_unary_op (etype); if (! error_state) @@ -84,6 +88,9 @@ if (! error_state && val.is_defined ()) { + profile_data_accumulator::enter pe (profiler, + "prefix " + oper ()); + // Attempt to do the operation in-place if it is unshared // (a temporary expression). if (val.get_count () == 1) @@ -153,6 +160,9 @@ { retval = ref.value (); + profile_data_accumulator::enter pe (profiler, + "postfix " + oper ()); + ref.do_unary_op (etype); } } @@ -162,6 +172,9 @@ if (! error_state && val.is_defined ()) { + profile_data_accumulator::enter pe (profiler, + "postfix " + oper ()); + retval = ::do_unary_op (etype, val); if (error_state)
--- a/src/sighandlers.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/sighandlers.cc Fri Aug 12 14:16:34 2011 -0400 @@ -945,6 +945,12 @@ return retval; } +/* +%!error SIG (1); +%!assert (isstruct (SIG ())); +%!assert (! isempty (SIG ())); +*/ + DEFUN (debug_on_interrupt, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} debug_on_interrupt ()\n\ @@ -958,6 +964,17 @@ return SET_INTERNAL_VARIABLE (debug_on_interrupt); } +/* +%!error (debug_on_interrupt (1, 2)); +%!test +%! orig_val = debug_on_interrupt (); +%! old_val = debug_on_interrupt (! orig_val); +%! assert (orig_val, old_val); +%! assert (debug_on_interrupt (), ! orig_val); +%! debug_on_interrupt (orig_val); +%! assert (debug_on_interrupt (), orig_val); +*/ + DEFUN (sighup_dumps_octave_core, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} sighup_dumps_octave_core ()\n\ @@ -970,6 +987,17 @@ return SET_INTERNAL_VARIABLE (sighup_dumps_octave_core); } +/* +%!error (sighup_dumps_octave_core (1, 2)); +%!test +%! orig_val = sighup_dumps_octave_core (); +%! old_val = sighup_dumps_octave_core (! orig_val); +%! assert (orig_val, old_val); +%! assert (sighup_dumps_octave_core (), ! orig_val); +%! sighup_dumps_octave_core (orig_val); +%! assert (sighup_dumps_octave_core (), orig_val); +*/ + DEFUN (sigterm_dumps_octave_core, args, nargout, "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {@var{val} =} sigterm_dumps_octave_core ()\n\ @@ -981,3 +1009,14 @@ { return SET_INTERNAL_VARIABLE (sigterm_dumps_octave_core); } + +/* +%!error (sigterm_dumps_octave_core (1, 2)); +%!test +%! orig_val = sigterm_dumps_octave_core (); +%! old_val = sigterm_dumps_octave_core (! orig_val); +%! assert (orig_val, old_val); +%! assert (sigterm_dumps_octave_core (), ! orig_val); +%! sigterm_dumps_octave_core (orig_val); +%! assert (sigterm_dumps_octave_core (), orig_val); +*/
--- a/src/symtab.h Fri Aug 12 14:05:48 2011 -0400 +++ b/src/symtab.h Fri Aug 12 14:16:34 2011 -0400 @@ -790,6 +790,11 @@ return rep->built_in_function; } + octave_value find_cmdline_function (void) const + { + return rep->cmdline_function; + } + octave_value find_autoload (void) { return rep->find_autoload (); @@ -1787,6 +1792,25 @@ return retval; } + static std::list<std::string> cmdline_function_names (void) + { + std::list<std::string> retval; + + for (fcn_table_const_iterator p = fcn_table.begin (); + p != fcn_table.end (); p++) + { + octave_value fcn = p->second.find_cmdline_function (); + + if (fcn.is_defined ()) + retval.push_back (p->first); + } + + if (! retval.empty ()) + retval.sort (); + + return retval; + } + static bool is_local_variable (const std::string& name) { if (xcurrent_scope == xglobal_scope)
--- a/src/sysdep.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/sysdep.cc Fri Aug 12 14:16:34 2011 -0400 @@ -586,8 +586,16 @@ return retval; } + DEFALIAS (setenv, putenv); +/* +%!assert (ischar (getenv ("OCTAVE_HOME"))); +%!test +%! setenv ("dummy_variable_that_cannot_matter", "foobar"); +%! assert (getenv ("dummy_variable_that_cannot_matter"), "foobar"); +*/ + // FIXME -- perhaps kbhit should also be able to print a prompt? DEFUN (kbhit, args, , @@ -695,6 +703,12 @@ return retval; } +/* +%!error (pause (1, 2)); +%!test +%! pause (1); +*/ + DEFUN (sleep, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} sleep (@var{seconds})\n\ @@ -724,6 +738,13 @@ return retval; } +/* +%!error (sleep ()); +%!error (sleep (1, 2)); +%!test +%! sleep (1); +*/ + DEFUN (usleep, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} usleep (@var{microseconds})\n\ @@ -760,6 +781,13 @@ return retval; } +/* +%!error (usleep ()); +%!error (usleep (1, 2)); +%!test +%! usleep (1000); +*/ + // FIXME -- maybe this should only return 1 if IEEE floating // point functions really work. @@ -776,6 +804,10 @@ || flt_fmt == oct_mach_info::flt_fmt_ieee_big_endian); } +/* +%!assert (islogical (isieee ())); +*/ + DEFUN (native_float_format, , , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} native_float_format ()\n\ @@ -787,6 +819,10 @@ return octave_value (oct_mach_info::float_format_as_string (flt_fmt)); } +/* +%!assert (ischar (native_float_format ())); +*/ + DEFUN (tilde_expand, args, , "-*- texinfo -*-\n\ @deftypefn {Built-in Function} {} tilde_expand (@var{string})\n\ @@ -835,3 +871,14 @@ return retval; } + +/* +%!test +%! if (isempty (getenv ("HOME"))) +%! setenv ("HOME", "foobar"); +%! endif +%! home = getenv ("HOME"); +%! assert (tilde_expand ("~/foobar"), fullfile (home, "foobar")); +%! assert (tilde_expand ("/foo/bar"), "/foo/bar"); +%! assert (tilde_expand ("foo/bar"), "foo/bar"); +*/
--- a/src/toplev.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/toplev.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1001,6 +1001,20 @@ DEFALIAS (shell_cmd, system); +/* +%!error (system ()); +%!error (system (1, 2, 3)); +%!test +%! if (ispc ()) +%! cmd = "dir"; +%! else +%! cmd = "ls"; +%! endif +%! [status, output] = system (cmd); +%! assert (ischar (output)); +%! assert (! isempty (output)); +*/ + // FIXME -- this should really be static, but that causes // problems on some systems. std::list<std::string> octave_atexit_functions; @@ -1439,6 +1453,15 @@ return retval; } +/* +%!error octave_config_info (1, 2); +%!assert (ischar (octave_config_info ("version"))); +%!test +%! x = octave_config_info (); +%! assert (isstruct (x)); +%! assert (! isempty (x)); +*/ + #if defined (__GNUG__) && defined (DEBUG_NEW_DELETE) int debug_new_delete = 0;
--- a/src/variables.cc Fri Aug 12 14:05:48 2011 -0400 +++ b/src/variables.cc Fri Aug 12 14:16:34 2011 -0400 @@ -1043,11 +1043,12 @@ const std::string& expr_str = std::string (), const octave_value& expr_val = octave_value ()) : name (expr_str.empty () ? sr.name () : expr_str), + varval (expr_val.is_undefined () ? sr.varval () : expr_val), is_automatic (sr.is_automatic ()), + is_complex (varval.is_complex_type ()), is_formal (sr.is_formal ()), is_global (sr.is_global ()), - is_persistent (sr.is_persistent ()), - varval (expr_val.is_undefined () ? sr.varval () : expr_val) + is_persistent (sr.is_persistent ()) { } void display_line (std::ostream& os, @@ -1117,13 +1118,14 @@ { case 'a': { - char tmp[5]; + char tmp[6]; tmp[0] = (is_automatic ? 'a' : ' '); - tmp[1] = (is_formal ? 'f' : ' '); - tmp[2] = (is_global ? 'g' : ' '); - tmp[3] = (is_persistent ? 'p' : ' '); - tmp[4] = 0; + tmp[1] = (is_complex ? 'c' : ' '); + tmp[2] = (is_formal ? 'f' : ' '); + tmp[3] = (is_global ? 'g' : ' '); + tmp[4] = (is_persistent ? 'p' : ' '); + tmp[5] = 0; os << tmp; } @@ -1172,11 +1174,12 @@ } std::string name; + octave_value varval; bool is_automatic; + bool is_complex; bool is_formal; bool is_global; bool is_persistent; - octave_value varval; }; public: @@ -1333,6 +1336,9 @@ for (size_t i = 0; i < param_string.length (); i++) param_length(i) = param_names(i) . length (); + // The attribute column needs size 5. + param_length(pos_a) = 5; + // Calculating necessary spacing for name column, // bytes column, elements column and class column @@ -1798,6 +1804,9 @@ Automatic variable. An automatic variable is one created by the\n\ interpreter, for example @code{argn}.\n\ \n\ +@item @code{c}\n\ +Variable of complex type.\n\ +\n\ @item @code{f}\n\ Formal parameter (function argument).\n\ \n\
--- a/test/fntests.m Fri Aug 12 14:05:48 2011 -0400 +++ b/test/fntests.m Fri Aug 12 14:16:34 2011 -0400 @@ -97,6 +97,17 @@ endif endfunction +function retval = has_demos (f) + fid = fopen (f); + if (fid >= 0) + str = fread (fid, "*char")'; + fclose (fid); + retval = ! isempty (regexp (str, '^%!demo', "lineanchors")); + else + error ("fopen failed: %s", f); + endif +endfunction + function [dp, dn, dxf, dsk] = run_test_dir (fid, d); global files_with_tests; global files_with_no_tests; @@ -113,6 +124,8 @@ [p, n, xf, sk] = test (nm(1:(end-2)), "quiet", fid); print_pass_fail (n, p); files_with_tests(end+1) = ffnm; + elseif (has_demos (ffnm)) + files_with_tests(end+1) = ffnm; else files_with_no_tests(end+1) = ffnm; endif @@ -164,6 +177,8 @@ dxf += xf; dsk += sk; files_with_tests(end+1) = f; + elseif (has_demos (f)) + files_with_tests(end+1) = f; elseif (has_functions (f)) ## To reduce the list length, only mark .cc files that contain ## DEFUN definitions. @@ -192,20 +207,15 @@ endfunction function n = num_elts_matching_pattern (lst, pat) - n = 0; - for i = 1:length (lst) - if (! isempty (regexp (lst{i}, pat, "once"))) - n++; - endif - endfor + n = sum (cellfun (@(x) !isempty (x), regexp (lst, pat, 'once'))); endfunction function report_files_with_no_tests (with, without, typ) - pat = cstrcat ("\\", typ, "$"); + pat = cstrcat ('\', typ, "$"); n_with = num_elts_matching_pattern (with, pat); n_without = num_elts_matching_pattern (without, pat); n_tot = n_with + n_without; - printf ("\n%d (of %d) %s files have no tests.\n", n_without, n_tot, typ); + printf ("\n%d (of %d) %s files have no tests or demos.\n", n_without, n_tot, typ); endfunction pso = page_screen_output (); @@ -258,6 +268,12 @@ puts ("because the needed libraries were not present when Octave was built.\n"); endif + ## Weed out deprecated and private functions + weed_idx = cellfun (@isempty, regexp (files_with_tests, '\bdeprecated\b|\bprivate\b', 'once')); + files_with_tests = files_with_tests(weed_idx); + weed_idx = cellfun (@isempty, regexp (files_with_no_tests, '\bdeprecated\b|\bprivate\b', 'once')); + files_with_no_tests = files_with_no_tests(weed_idx); + report_files_with_no_tests (files_with_tests, files_with_no_tests, ".m"); report_files_with_no_tests (files_with_tests, files_with_no_tests, ".cc");
--- a/test/test_parser.m Fri Aug 12 14:05:48 2011 -0400 +++ b/test/test_parser.m Fri Aug 12 14:16:34 2011 -0400 @@ -28,142 +28,222 @@ %!assert ({1 2,{3,4}}, {1,2,{3,4}}) %!assert ({1,2,{3 4}}, {1,2,{3,4}}) -%# Tests for operator precedence as documented in section 8.8 of manual -%# There are 11 levels of precedence from "exponentiation" (highest) down to -%# "statement operators" (lowest). -%# -%# Level 11 (exponentiation) overrides all others +## Tests for operator precedence as documented in section 8.8 of manual +## There are 13 levels of precedence from "parentheses and indexing" (highest) +## down to "statement operators" (lowest). +## +## Level 13 (parentheses and indexing) +## Overrides all other levels +%!test +%! a.b = 1; +%! assert (a. b++, 1) +%! assert (a.b, 2) +%! clear a; +%! a.b = [0 1]; +%! b = 2; +%! assert (a.b', [0;1]) +%! assert (!a .b, logical ([1 0])) +%! assert (3*a .b, [0 3]) +%! assert (a. b-1, [-1 0]) +%! assert (a. b:3, 0:3) +%! assert (a. b>0.5, logical ([0 1])) +%! assert (a. b&0, logical ([0 0])) +%! assert (a. b|0, logical ([0 1])) +%! a.b = [1 2]; +%! assert (a. b&&0, false) +%! assert (a. b||0, true) +%! a.b += a. b*2; +%! assert (a.b, [3 6]) +## Level 12 (postfix increment and decrement) %!test -%! assert (-2^2, -4) -%! assert (!0^0, false); -# FIXME: This test is failing. Transpose mistakenly has higher priority. -%!# assert ([2 3].^2', [4; 9]) -%! assert (2*3^2, 18) -%! assert (2+3^2, 11) -%! assert ([1:10](1:2^2), [1 2 3 4]) -%! assert (3 > 2^2, false) -%! assert (1 & 0^0, true) -%! assert (1 && 0^0, true) +%! a = [3 5]; +%! assert (2.^a ++, [8 32]) +%! assert (a, [4 6]) +%! assert (a--', [4; 6]) +%! assert (a, [3 5]) +%! a = 0; +%! assert (!a --, true) +%! assert (-a ++, 1) +%! assert (3*a ++, 0) +%! assert (a++-2, -1) +%! assert (1:a ++, 1:2) +%! assert (4>a++, true) +%! a = [0 -1]; +%! assert ([1 1] & a++, logical ([0 1])) +%! assert ([0 0] | a++, logical ([1 0])) +%! a = 0; +%! assert (1 && a ++, false) +%! assert (0 || a --, true) +%! a = 5; b = 2; +%! b +=a ++; +%! assert (b, 7) + +## Level 11 (transpose and exponentiation) +%!test +%! assert (-2 ^2, -4) +%! assert (!0 ^0, false) +%! assert (2*3 ^2, 18) +%! assert (2+3 ^2, 11) +%! assert ([1:10](1:2 ^2), [1 2 3 4]) +%! assert (3>2 ^2, false) +%! assert (1&0 ^0, true) +%! assert (0|0 ^0, true) +%! assert (1&&0 ^0, true) +%! assert (0||0 ^0, true) %! a = 3; -%! a *= 0^0; +%! a *= 0 ^0; %! assert (a, 3) -%# Level 10 (unary plus, increment, not) +## Level 10 (unary plus/minus, prefix increment/decrement, not) %!test -# FIXME: No test for increment and transpose that I can think of. %! a = 2; -%! assert (++a*3, 9) -%! assert (a++-2, 1) -%! assert (a, 4) -%! assert ([1:10](1:++a), [1:5]) -%! assert (5 == a++, true) -%! assert (7 == ++a, true) +%! assert (++ a*3, 9) +%! assert (-- a-2, 0) +%! assert (a, 2) +%! assert (! a-2, -2) +%! assert ([1:10](++ a:5), 3:5) +%! a = [1 0]; +%! assert (! a>=[1 0], [false true]) %! a = 0; -%! assert (1 & a++, false) -%! assert (a, 1) -%! assert (1 && --a, false) +%! assert (++ a&1, true) +%! assert (-- a|0, false) +%! assert (-- a&&1, true) +%! assert (++ a||0, false) %! a = 3; -%! a *= a++; -%! assert (a, 12) -%# Level 9 (transpose) +%! a *= ++a; +%! assert (a, 16) +## Level 9 (multiply, divide) %!test -%! assert ([1 2]*[3 4]', 11) -%! assert ([1 2]'+[3 4]', [4; 6]) -%! assert (1:5', 1:5) -%! assert ([1; 2] == [1 2]', [true; true]) -%! assert ([1; 0] & [1 0]', [true; false]) -# FIXME: No test for transpose and short-circuit operator that I can think of. -%! a = [1 2]; -%! a *= [3 4]'; -%! assert (a, 11) -%# Level 8 (multiply, divide) -%!test -%! assert (3 + 4 * 5, 23) -%! assert (3 + 4 * 5, 23) -%! assert (5*1:6, [5 6]) -%! assert (3 > 1 * 5, false) -%! assert (1 & 1 * 0, false) -%! assert (1 && 1 * 0, false) +%! assert (3+4 * 5, 23) +%! assert (5 * 1:6, [5 6]) +%! assert (3>1 * 5, false) +%! assert (1&1 * 0, false) +%! assert (1|1 * 0, true) +%! assert (1&&1 * 0, false) +%! assert (1||1 * 0, true) %! a = 3; %! a /= a * 2; %! assert (a, 0.5) -%# Level 7 (add, subtract) +## Level 8 (add, subtract) %!test %! assert ([2 + 1:6], 3:6) -%! assert (3 > 1 + 5, false) -%! assert (1 & 1 - 1, false) -%! assert (1 && 1 - 1, false) +%! assert (3>1 + 5, false) +%! assert (1&1 - 1, false) +%! assert (0|1 - 2, true) +%! assert (1&&1 - 1, false) +%! assert (0||1 - 2, true) %! a = 3; %! a *= 1 + 1; %! assert (a, 6) -%# Level 6 (colon) +## Level 7 (colon) %!test -%! assert (5:-1: 3 > 4, [true false false]) -%! assert (1: 3 & 1, [true true true]) -%! assert (-1: 3 && 1, false) +%! assert (5:-1: 3>4, [true false false]) +%! assert (1: 3&1, [true true true]) +%! assert (1: 3|0, [true true true]) +%! assert (-1: 3&&1, false) +%! assert (-1: 3||0, false) %! a = [1:3]; %! a += 3 : 5; %! assert (a, [4 6 8]) -%# Level 5 (relational) +## Level 6 (relational) %!test -%! assert (0 == -1 & 0, false) -%! assert (0 == -1 && 0, false) +%! assert (0 == -1&0, false) +%! assert (1 == -1|0, false) +%! assert (0 == -1&&0, false) +%! assert (1 == -1||0, false) %! a = 2; %! a *= 3 > 1; %! assert (a, 2) -%# Level 4 (element-wise and, or) +## Level 5 (element-wise and) %!test -%! assert (0 & 1 || 1, true) -%! assert (0 == -1 && 0, false) +%! assert (0 & 1|1, true) +%! assert ([0 1] & 1&&1, false) +%! assert (0 & 1||1, true) %! a = 2; %! a *= 3 & 1; %! assert (a, 2) -%# Level 3 (logical and, or) +## Level 4 (element-wise or) %!test +%! assert ([0 1] | 1&&0, false) +%! assert ([0 1] | 1||0, true) +%! a = 2; +%! a *= 0 | 1; +%! assert (a, 2) +## Level 3 (logical and) +%!test +%! assert (0 && 1||1, true) %! a = 2; %! a *= 3 && 1; %! assert (a, 2) +## Level 2 (logical or) +%!test +%! a = 2; +%! a *= 0 || 1; +%! assert (a, 2) -%# Tests for operator precedence within each level where ordering should -%# be left to right except for exponents and assignments. -%# Level 11 (exponentiation) +## Tests for operator precedence within each level where ordering should +## be left to right except for postfix and assignment operators. + +## Level 13 (parentheses and indexing) %!test -%# FIXME : Exponentiation seems to work left to right, despite the -%# documentation and ordinary mathematical rules of precedence. -%!# assert (2^3**2, 512) -%# Level 10 (unary plus, increment, not) +%! a.b1 = 2; +%! assert (a.(strcat('b','1'))++, 2) +%! assert (a.b1, 3) +%! b = {1 2 3 4 5}; +%! assert (b{(a. b1 + 1)}, 4) +%! b = 1:5; +%! assert (b(a. b1 + 1), 4) +%! assert ([2 3].^2', [4; 9]) +## Level 12 (postfix increment and decrement) +## No tests possible since a++-- is not valid +## Level 11 (transpose and exponentiation) +## Note: Exponentiation works left to right for compatibility with Matlab. +%! assert (2^3**2, 64) +%! assert ([2 3].^2.', [4;9]) +%! assert ([2 3].'.^2, [4;9]) +%! assert (3*4i'.', 0 - 12i) +%! assert (3*4i.'.', 0 + 12i) +## Level 10 (unary plus/minus, prefix increment/decrement, not) %!test %! assert (+-+1, -1) -%! a = 0; -%# FIXME : Should we test for this corner case at all? -%# (unary minus)(auto-decrement operator) -%!# assert (---a, 1); %! a = -1; %! assert (!++a, true) %! assert (a, 0) %! assert (-~a, -1) -%! assert (!~a++, false) -%! assert (a, 1) -%# Level 9 (transpose) +%! assert (!~--a, true) +%! assert (a, -1) +## Level 9 (multiply, divide) %!test -%! assert (3*4i'.', 0 - 12i) -%! assert (3*4i.'.', 0 + 12i) -%# Level 8 (multiply, divide) +%! assert (3 * 4 / 5, 2.4) +%! assert (3 ./ 4 .* 5, 3.75) +%! assert (2 * 4 \ 6, 0.75) +%! assert (2 .\ 4 .* 6, 12) +## Level 8 (add, subtract) %!test -%!assert (3 * 4 / 5, 2.4) -%!assert (3 ./ 4 .* 5, 3.75) -%# Level 7 (add, subtract) -%!test -%!assert (-3 - 4 + 1 + 3 * 2, 0) -%# Level 5 (relational) +%! assert (-3 - 4 + 1 + 3 * 2, 0) +## Level 7 (colon) +## No tests possible because colon operator can't be combined with second colon operator +## Level 6 (relational) %!test %! assert (0 < 1 <= 0.5 == 0 >= 0.5 > 0, true) %! assert (1 < 1 == 0 != 0, true) %! assert (1 < 1 == 0 ~= 0, true) -%# Level 4 (element-wise and, or) +## Level 5 (element-wise and) +## No tests possible. Only one operator (&) at this precedence level and operation is associative. +## Level 4 (element-wise or) +## No tests possible. Only one operator (|) at this precedence level and operation is associative. +## Level 3 (logical and) %!test -%! assert ([ 1 0] & [0 1] | [1 0], [true false]) -%# Level 2 (assignment) +%! a = 1; +%! assert (1 && 0 && ++a, false) +%! assert (a, 1) +## Level 2 (logical or) +%!test +%! a = 1; +%! assert (0 || 1 || ++a, true) +%! assert (a, 1) +## Level 1 (assignment) %!test %! a = 2; b = 5; c = 7; %! assert (a += b *= c += 1, 42) %! assert (b == 40 && c == 8) +