1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
# extra_string.inp for string-related functions
## multi_instrings
# was inherited from SVAR where it was called names2indices.
# However, this returns the raw unsorted indices (possibly
# with multiple occurrences).
# Another difference: When the second argument is an empty array,
# then an empty matrix is returned (used to be the opposite, a vector
# with _all_ indices).
# (Adding a "null" default for the 2nd argument and then returning
# all the indices seems unnecessary, because a user then could always
# do seq(1,nelem(lookinhere))' instead.)
function matrix multi_instrings (strings lookinhere, strings tofind)
# Returns the positions (indices) in 'lookinhere' where any of the
# strings from 'tofind' occur.
# If there are duplicates in 'tofind' then the output may also
# contain duplicate indices. Use uniq() or values() afterwards
# if needed.
# This function requires version 2020a.
matrix which = {}
# The case !nelem(tofind) used to be (in SVAR) some sort of default
# and returned all indices instead of none
# (don't remember why)
# which = seq(1, nelem(lookinhere))
if nelem(tofind)
loop n = 1..nelem(tofind)
which |= instrings(lookinhere, tofind[n])
endloop
endif
return which # may still be empty
end function
####################
function strings powerset (strings S)
/* Computes the powerset of the input S, i.e. all possible combinations
of the string elements in S. (Including the empty set / empty
string "".) Each combination yields one string in the output array.
Being a set, the ordering is not defined. */
scalar l = nelem(S)
scalar N = 2^l
matrix P = zeros(N, l)
matrix s = seq(0, N-1)'
strings PS = array(N)
loop i = 1..l
matrix a = s % 2
P[,i] = a
s = (s - a) / 2
endloop
loop i = 1..N
string c = ""
loop j = 1..l
if P[i, j]
c = c ~ " " ~ S[j]
endif
endloop
PS[i] = c
endloop
return PS
end function
######################
function void splitfname_check (strings out, int num)
# Just a stupid debug checker and error catcher
# for splitfname.
if nelem(out) != num
print out
funcerr "Shouldn't happen (weird input?)"
endif
end function
function strings splitfname (const string fn)
/* The idea is to take a file name or full path and extract
up to 3 components:
1. The path prefix (may be empty; without the trailing / or \ )
2. The "base" component of the file name, without the
extension and without the path prefix
3. The file extension (without the dot; may be empty)
Example:
Input string: "/what/on/earth/isthisfile.gdt"
Output:
defarray("/what/on/earth", "isthisfile", "gdt")
(To separate the path prefix we just look for the last / _OR_
\ (forward or backward slash) and also think of the possibility of //.)
We use the \t character as internal separator because \n doesn't
work properly with strsplit (bug fixed in gretl Dec 17th, 2019, for 2019d).
*/
hasslash = instring(fn, "/") || instring(fn, sprintf("\\"))
# Test for a dot in a position where it signals an extension
# (not the Unixy other meanings)
hasext = 0
if regsub(fn, ".*[\w\s]+\.[\w\s]+", "!") == "!" && (fn != "!")
hasext = 1
endif
if hasext && hasslash # the full monty
string sepa = regsub(fn, "(.*)[/\\]+([^/\\]*)\.([^\./\\]*)", \
"\1\t\2\t\3")
strings out = strsplit(sepa, "\t")
splitfname_check(out, 3)
elif hasext # only base file name and ext, no prefix
string sepa = regsub(fn, "(.*)\.([^\.]*)", "\1\t\2")
strings parts = strsplit(sepa, "\t")
splitfname_check(parts, 2)
strings out = defarray("") + parts # empty prefix first
elif hasslash # no extension
string sepa = regsub(fn, "(.*)[/\\]+([^/\\]*)", "\1\t\2")
strings parts = strsplit(sepa, "\t")
splitfname_check(parts, 2)
strings out = parts + defarray("") # empty ext last
else # no slash, no ext, just simple filename
strings out = defarray("", fn, "")
endif
return out
end function
###
### Auxiliary functions for mat2latex
###
function strings auto_names(int n, string prefix)
strings ret = array(n)
loop i = 1 .. n
ret[i] = sprintf("%s %d", prefix, i)
endloop
return ret
end function
function bundle m2ltx_default_opts(scalar r, scalar c)
bundle ret = null
scalar ret.decimals = 3
string ret.nacode = ""
strings ret.rnames = auto_names(r, "Row")
strings ret.cnames = auto_names(c, "Col")
string s = "l"
loop i = 1 .. c
s = s ~ "c"
endloop
ret.format = s
return ret
end function
### the mat2latex function proper
function string mat2latex (matrix mprint, bundle useropts[null])
scalar nc = cols(mprint)
scalar nr = rows(mprint)
opts = m2ltx_default_opts(nr, nc)
strings labs = rnameget(mprint)
if nelem(labs)
opts.rnames = labs
endif
strings labs = cnameget(mprint)
if nelem(labs)
opts.cnames = labs
endif
if exists(useropts)
# override defaults
opts = useropts + opts
endif
fmtstr = sprintf("%%.%df", opts.decimals)
string ret = ""
outfile --buffer=ret --quiet
printf "\begin{tabular}{%s}\n", opts.format
printf "\\hline\n &\t"
# Print column names
n = nelem(opts.cnames)
loop i = 1 .. n
printf "%s ", opts.cnames[i]
if i<n
printf " &\t "
else
printf "\\\ \hline\n"
endif
endloop
# Printf Rows
loop i = 1 .. nr
printf "%s", opts.rnames[i]
loop j = 1 .. nc
scalar x = mprint[i,j]
if isnan(x)
printf " & %s\t", opts.nacode
else
printf " & @fmtstr", x
endif
if j < nc
printf "\t"
else
printf " \\\ \n"
endif
endloop
endloop
printf "\\hline\n"
printf "\end{tabular}\n"
end outfile
return ret
end function
|