Code covered by the BSD License  

Highlights from
Chebfun V4

image thumbnail

Chebfun V4

by

 

30 Apr 2009 (Updated )

Numerical computation with functions instead of numbers.

Editor's Notes:

This file was selected as MATLAB Central Pick of the Week

scribble.m
function f = scribble(varargin)
%SCRIBBLE  Writing text with chebfuns
%  SCRIBBLE('STRING') returns a complex chebfun representing the text in
%  STRING. The full United States QWERTY keyboard layout is supported
%  (though letters will be printed only in upper-case), as well as some
%  special and international characters.  To contribute a character, please
%  write it and email it to develop@chebfun.org.
%
%  SCRIBBLE(STRING,N) returns a quasimatrix of complex chebfuns, where 
%  STRING has been split into N substrings, each on a separate line.
%
%  SCRIBBLE('STRING_1',STRING_2',...,'STRING_N') or
%  SCRIBBLE({'STRING_1',STRING_2',...,'STRING_N'}) also returns a quasimatrix
%  of complex chebfuns, with column k of the quasimatrix (i.e. row k of
%  the text when plotted) representing the text in STRING_K.
%
%  Examples:
%   f = scribble('The quick brown fox jumps over the lazy dog. 0123456789');
%   plot(f), axis equal
% 
%   f = scribble('The quick brown fox jumps over the lazy dog. 0123456789',4); 
%   plot(f), axis equal
% 
%   f = scribble('The quick brown','fox jumps over','the lazy dog.','0123456789'); 
%   plot(f), axis equal
%
%   f = scribble({'The quick brown','fox jumps over','the lazy dog.','0123456789'}); 
%   plot(f), axis equal

%  Copyright 2011 by The University of Oxford and The Chebfun Developers.
%  See http://www.maths.ox.ac.uk/chebfun/ for Chebfun information.

    if nargin == 0
        f = scribbleMultipleLines({ ...
            '-> supply your <-', ...
            '->own string to<-', ... 
            '->scribble  it!<-'});
    elseif nargin == 1 && ischar(varargin{1})
        % if the input is a single line of text, scribble the one line
        f = scribbleOneLine(varargin{1});
    elseif nargin == 1 && iscell(varargin{1})
        % if the input is a cell array of strings, scribble each one as a
        % column in a quasimatrix (where each vertically offset to form a
        % paragraph)
        f = scribbleMultipleLines(varargin{1});
    elseif nargin == 2 && ischar(varargin{1}) && isnumeric(varargin{2})
        % split the single line of text provided into an N-line paragraph
        % quasimatrix
        s = splitIntoNStrings(varargin{1},varargin{2});
        f = scribbleMultipleLines(s);
    elseif nargin >= 2 && all(cellfun(@ischar,varargin))
        % accept multiple string input outside of a cell-array
        f = scribbleMultipleLines(varargin);
    else
        error('CHEBFUN:scribble:invalidinputs', ...
            'Scribble takes only strings or a cell-array of strings as input');
    end

end

function f = scribbleOneLine(s)
%SCRIBBLEONELINE  Writes a single line of text with chebfuns

    L = length(s);
    f0 = {};
    ends = [0 1];
    for j = 1:L
        switch upper(s(j))
            % Alphabet
            case {'A'}, t = c([0 .4+1i .8 .6+.5i .2+.5i]);
            case {'B'}, t = c([0 1i .8+.9i .8+.6i .5i .8+.4i .8+.1i 0]);
            case {'C'}, t = c([.8+1i .8i .2i .8]);
            case {'D'}, t = c([0 .8+.1i .8+.9i 1i 0]);
            case {'E'}, t = c([.8+1i 1i .5i .5i+.7 .5i 0 .8]);
            case {'F'}, t = c([.8+1i 1i .5i .5i+.7 .5i 0]);
            case {'G'}, t = c([.8+1i .8i .2i .6 .6+.5i .4+.5i .8+.5i]);
            case {'H'}, t = c([0 1i .5i .5i+.8 .8+1i .8]);
            case {'I'}, t = c([0 .8 .4 .4+1i 1i .8+1i]);
            case {'J'}, t = c([0 .4 .4+1i 1i .8+1i]);
            case {'K'}, t = c([0 1i .5i .8+1i .5i .8]);
            case {'L'}, t = c([1i 0 .8]);
            case {'M'}, t = c([0 .1+1i .4 .7+1i .8]);
            case {'N'}, t = c([0 1i .8 .8+1i]);
            case {'O'}, t = c([0 1i .8+1i .8 0]);
            case {'Q'}, t = c([0 1i .8+1i .8 .6+.2i .9-.1i .8 0]);
            case {'P'}, t = c([0 1i .8+1i .8+.5i .5i]);
            case {'R'}, t = c([0 1i .8+1i .8+.6i .5i .8]);
            case {'S'}, t = c([.8+1i .9i .6i .8+.4i .8+.1i 0]);
            case {'T'}, t = c([.4 .4+1i 1i .8+1i]);
            case {'U'}, t = c([1i .1 .7 .8+1i]);
            case {'V'}, t = c([1i .4 .8+1i]);
            case {'W'}, t = c([1i .2 .4+1i .6 .8+1i]);
            case {'X'}, t = c([1i .8 .4+.5i .8+1i 0]);
            case {'Y'}, t = c([1i .4+.5i .8+1i .4+.5i .4]);
            case {'Z'}, t = c([1i .8+1i 0 .8]);
                % Numerals
            case {'0'}, t = c([0 1i .8+1i 0 .8 .8+1i]);
            case {'1'}, t = c([0 .8 .4 .4+1i .1+.8i]);
            case {'2'}, t = c([.8 0 .5i .8+.5i .8+1i 1i]);
            case {'3'}, t = c([1i .8+1i .8+.5i .1+.5i .8+.5i .8 0]);
            case {'4'}, t = c([1i .5i .8+.5i .8+1i .8]);
            case {'5'}, t = c([.8+1i 1i .5i .8+.5i .8 0]);
            case {'6'}, t = c([.8+1i 1i 0 .8 .8+.5i .5i]);
            case {'7'}, t = c([1i .8+1i .2]);
            case {'8'}, t = c([1i .8+1i .8 0 .5i 1i .5i .8+.5i]);
            case {'9'}, t = c([.8 .8+1i 1i .5i .8+.5i]);
                % Punctuation
            case {'.'}, t = c([0 .05 .05+.05i .05i 0]);
            case {','}, t = c([-0.1-.15i -.05-.15i .1+.05i .05+.05i -.1-.15i]);
            case {';'}, t = [c([-0.1-.15i -.05-.15i .1+.05i .05+.05i -.1-.15i]+.375+.3i) c([.05 .1 .1+.05i .05+.05i .05]+.375+.7i)];
            case {':'}, t = [c([0 .05 .05+.05i .05i 0]+.375+.3i) c([0 .05 .05+.05i .05i 0]+.375+.7i)];
            case {'?'}, t = [c([.6i 1i .8+1i .8+.5i .4+.5i .4+.2i]) c([.35 .45 .45+.05i .35+.05i .35])];
            case {'!'}, t = [c([.4+1i .4+.2i]) c([.35 .45 .45+.05i .35+.05i .35])];
            case {''''}, t = c([.3+.7i .4+1i]);
            case {'"'}, t = [c([.33+.8i .33+1i]) c([.66+.8i .66+1i])];
            case {'`'}, t = c([.5+.7i .4+1i]);
            case {'_'}, t = c([-.1 .9]);
            case {' '}, t = []; % Space
                % Parentheses
            case {')'}, t = c([.3+1i .4+.9i .5+.75i .5+.25i .4+.1i .3]);
            case {'('}, t = c([.5+1i .4+.9i .3+.75i .3+.25i .4+.1i .5]);
            case {'['}, t = c([.5 .3 .3+1i .5+1i]);
            case {']'}, t = c([.3 .5 .5+1i .3+1i]);
            case {'{'}, t = c([.5 .4+.1i .4+.4i .3+.5i .4+.6i .4+.9i .5+1i]);
            case {'}'}, t = c([.3 .4+.1i .4+.4i .5+.5i .4+.6i .4+.9i .3+1i]);
                % Symbols (math)
            case {'-'}, t = c([.1+.5i .7+.5i]);
            case {'+'}, t = c([.5i .8+.5i .4+.5i .4+.9i .4+.1i]);
            case {'*'}, t = [c([.4+.7i .4+.9i]) c([.32+.73i .48+.87i]) c([.48+.73i .32+.87i])];
            case {'/'}, t = c([.2 .6+1i]);
            case {'^'}, t = c([.2+.7i .4+1i .6+.7i]);
            case {'='}, t = [c([.1+.4i .7+.4i]) c([.1+.6i .7+.6i])];
            case {'<'}, t = c([.6+.3i .2+.5i .6+.7i]);
            case {'>'}, t = c([.2+.3i .6+.5i .2+.7i]);
                % Symbols (other)
            case {'\'}, t = c([.6 .2+1i]);
            case {'|'}, t = c([.4 .4+1i]);
            case {'¬'}, t = c([.1+.6i .7+.6i .7+.4i]);
            case {'%'}, t = [c([.1 .7+1i]) c(3*[0 .05 .05+.05i .05i 0]+.2+.85i) c(3*[0 .05 .05+.05i .05i 0]+.5+.05i)];
            case {'#'}, t = [c([.3+.1i .3+.9i]) c([.5+.1i .5+.9i]) c([.2+.3i .6+.3i]) c([.2+.7i .6+.7i])];
            case {'~'}, t = c([.2+.45i .3+.55i .5+.45i .6+.55i]);
            case {'@'}, t = c([.8 0 1i .8+1i .8+.25i .2+.25i .2+.75i .6+.75i .6+.25i]);
            case {'$'}, t = [c([.8+1i .9i .6i .8+.4i .8+.1i 0]) c([.4 .4+1i])];
            case {'£'}, t = c([.8+1i .3+1i .2+.5i .5+.5i .5i .2+.5i .2 0.1 .8]);
            case {'&'}, t = c([.8 .7i 1i .7+1i .7+.7i .3i 0 .4 .8+.27i]);
                % Misc
            case {'Ê'}, t = [c([.8+1i 1i .5i .5i+.7 .5i 0 .8]) c([.1+1.1i .4+1.2i .7+1.1i])];
            case {'Þ'}, t = c([0 1i .8+1i .8+.5i .5i]);
            case {'Æ'}, t = c([0 .4+1i .8+1i .4+1i .4 .8 .4 .4+.5i .2+.5i .6+.5i]);
            case {'?'}, t = [c([0 .8 .4 .4+1i 1i .8+1i]) c([.2+1.1i .6+1.2i])];

            otherwise,
                t = [];
                warning('CHEBFUN:scribble:unknownchar', ...
                    ['"', s(j), '" is not supported by scribble. (But please feel ', ...
                    'free write it and email it to develop@chebfun.org)']);
        end

        if ~isempty(t)
            f0 = [f0 , t];
        end

    end
    
    % Rescale the ends to [-1 1]
    ends = 2*(0:ends(1))/ends(1)-1;
    
    % Adjust the intervals accordingly
    for k = 1:numel(f0);
        f0{k}{2} = ends(k:k+1);
    end

    % Construct the funs all at once
    f0 = fun( f0 );

    % Construct global chebfun on [-1 1]
    if isempty(f0), f = chebfun; return, end
    f = chebfun(0,ends([1 end]));
    imps = zeros(size(ends));
    for k = 1:numel(f0)
        imps(1,k) = f0(k).vals(1);
    end
    imps(1,end) = f0(end).vals(end);
    f = set(f,'ends',ends,'funs',f0,'imps',imps);

    function cf = c(v)
        cf = {};
        for l = 2:length(v)
            cf{end+1} = { (v(l-1:l)+(j-1))*2/L-1 , [] };
            ends = ends + 1;
        end
    end

end

function f = scribbleMultipleLines(s)
%SCRIBBLEMULTIPLELINES  Writes a multiple line of text with chebfuns

    f = [];
    N = numel(s);

    for n = 1:N
        tmp = scribbleOneLine(s{n});
        h = 2.4./numel(s{n});
        f = [f+1i*h tmp];
    end

end

function sCell = splitIntoNStrings(sStr,N)
%SPLITINTONSTRINGS splits a single line of text into N lines of text

    try
        L = length(sStr);
        if N > L
            N = L;
        elseif N <= 0
            N = 1;
        end
        inds = round(linspace(0,L,N+1));
        sCell = cell(1,N);
        for n = 1:N
            sCell{n} = sStr(inds(n)+1:inds(n+1));
        end
    catch
        error('CHEBFUN:scribble:splitIntoNStrings',...
            ['We do not know how to break up your %i strings ' ...
            'into %i sentances'],numel(s),N);
    end

end

Contact us