Plotting irregularly-spaced arrays in gnuplot 5.x - arrays

gnuplot 5.x now supports arrays, but there seems to be no way to plot, or fit, to an irregularly-spaced set of data, if it is not provided in an external file. What I would like to see is the ability to plot "y vs x":
array z[8]=[0,1,2,3,4,5,6,6.4]
array f[8]=[0.468,0.405,0.342,0.279,0.216,0.153,0.090,0.064]
plot z,f
or even
plot [3,3],[0,0.25] w lines
which would, for example, provide a handy vertical marker line at x=3 without needing to resort to arrows without heads:
plot '+' using (3):(0):(0):(0.25) with vectors nohead
One can achieve the plotting in this awkward-looking way:
plot sample [j=1:|x|] '+' using (x[j]):(y[j])
but, unfortunately, the same syntax is not recognized by the fit command.
The only way I figured so far is to write the data to a virtual file (a data block), and use it as input to both plot and fit commands:
set print $DATA
print sprintf("# z\tf") ## header line, overwrite old content if any
set print $DATA append ## append data lines
do for [j=1:|z|] {
print sprintf("%f\t%f",z[j],f[j])
}
unset print
y(x)=m*x-y0
y0=0.25
m=1
fit y(x) $DATA via m,y0
plot $DATA t 'data',y(x) w lines t 'fit'
Is there a better way? Or can someone explain to me why such an obvious task is not a part of the standard plot/array implementation? It certainly would be one of the first things on my wish list.

What describe is exactly the purpose of data blocks:
$DATA <<EOD
0 0.468
1 0.405
2 0.342
3 0.279
4 0.216
5 0.153
6 0.090
6.4 0.064
EOD
y(x)=m*x-y0
y0=0.25
m=1
fit y(x) $DATA via m,y0
plot $DATA t 'data',y(x) w lines t 'fit'

Thanks Christoph for extensive help. It has emerged that data block syntax together with the appropriate "using" options would achieve what I had set out to do. Inline specification for a data block is perfectly compact, and the pre-processing can be replaced for both plot... and fit... with identical syntax:
$DATA <<EOD
0 0.468
1 0.405
2 0.342
3 0.279
4 0.216
5 0.153
6 0.090
6.4 0.064
EOD
y(x)=m*(x-x0)**2+y0
y0=0.9
m=-0.1
x0=4
fit y(x) $DATA using ($1):($1)*($2) via m,x0,y0
plot $DATA using ($1):($1)*($2) t 'data',y(x) w lines t 'fit'

To plot the data stored in arrays as it is, you can write it in the following way (I tried this in version 5.4).
array z[8]=[0,1,2,3,4,5,6,6.4]
array f[8]=[0.468,0.405,0.342,0.279,0.216,0.153,0.090,0.064]
plot z using (z[$0+1]):(f[$0+1])
At first glance, it seems that (z[$0+1]) in using can be replaced by 1, but in the version I tried, I had to do this.

Related

Is it possible to insert a matrix bigger than 10x10 in LaTeX? [duplicate]

I have a 3x12 matrix I'd like to input into my LaTeX (with amsmath) document but LaTeX seems to choke when the matrix gets larger than 3x10:
\begin{equation}
\textbf{e} =
\begin{bmatrix}
1&1&1&1&0&0&0&0&-1&-1&-1&-1\\
1&-1&0&0&1&1&-1&-1&0&0&1&-1\\
0&0&1&-1&1&-1&1&-1&1&-1&0&0
\end{bmatrix}
\end{equation}
The error: Extra alignment tab has been changed to \cr. tells me that I have more & than the bmatrix environment can handle. Is there a proper way to handle this? It also seems that the alignment for 1's and the -1's are different, is that also expected of the bmatrix?
From the amsmath documentation (texdoc amsmath):
The amsmath package provides some
environments for matrices beyond the
basic array environment of LATEX. The
pmatrix, bmatrix, Bmatrix, vmatrix and
Vmatrix have (respectively) ( ), [
], { }, | |, and ∥
∥ delimiters built in. For naming
consistency there is a matrix
environment sans delimiters. This is
not entirely redundant with the array
environment; the matrix environments
all use more economical horizontal
spacing than the rather prodigal
spacing of the array environment.
Also, unlike the array environment,
you don’t have to give column
specifications for any of the matrix
environments; by default you can have
up to 10 centered columns. (If you
need left or right alignment in a
column or other special formats you
must resort to array.)
i.e. bmatrix defaults to a 10 column maximum.
A footnote adds
More precisely: The maximum number of
columns in a matrix is determined by
the counter MaxMatrixCols (normal
value = 10), which you can change if
necessary using LATEX’s \setcounter or
\addtocounter commands.
If you came to this page looking for the exact command (thanks to Scott Wales for the answer), you want this in your preamble:
\setcounter{MaxMatrixCols}{20}
Where you can replace 20 with the maximum number of columns you want.
The answer by Scott is correct, but I've since learned you can override the alignment. Taken from http://texblog.net/latex-archive/maths/matrix-align-left-right/
\makeatletter
\renewcommand*\env#matrix[1][c]{\hskip -\arraycolsep
\let\#ifnextchar\new#ifnextchar
\array{*\c#MaxMatrixCols #1}}
\makeatother
Now allows the command:
\begin{bmatrix}[r] ....
to have right-alignment!
Instead of a bmatrix you can use +bmatrix from the tabularray package:
\documentclass{article}
\usepackage{tabularray}
\UseTblrLibrary{amsmath}
\begin{document}
\begin{equation}
\textbf{e} =
\begin{+bmatrix}
1&1&1&1&0&0&0&0&-1&-1&-1&-1\\
1&-1&0&0&1&1&-1&-1&0&0&1&-1\\
0&0&1&-1&1&-1&1&-1&1&-1&0&0
\end{+bmatrix}
\end{equation}
\end{document}

Difficulty initialising an array of strings in structured text

Structured text seems to delight in making the simple really difficult (much more used to C). Could somebody please rearrange this so it will compile.
VAR_GLOBAL
ErrorStg : Array[0 .. 10] of STRING[16] := "Good","Bad","Fsked";
END_VAR
Did you read the compiler error at all...?
The working version at least on CODESYS 3 based platforms:
ErrorStg : ARRAY[0 .. 10] OF STRING[16] := ['Good','Bad','Fsked'];
The working version at least on CODESYS 2 based platforms:
ErrorStg : ARRAY[0 .. 10] OF STRING[16] := 'Good', 'Bad', 'Fsked';
You should use ' instead of " with regular strings.
When you initialize an array on the definition line, you have to give all of the values (all 11 in your case).
As an alternative, I would suggest a much easier solution - use an init routine to assign the values. If you are opposed to “burning boot time”, you can still solve by defining a FB called InitGlobals and then define a FB_INIT method and put your assignments there. FB_INIT executes as soon as the object exists and not when your program runs. Add an instance of InitGlobals to your code, of course.

Wordpress Array Conundrum

I have the following array output which I'd like to merge:
004249512651280042495126512800424951265128
There are 3 seperate arrays there, which are outputting data from a database, which has these numbers populated. These are the arrays:
00424951265128
00424951265128
00424951265128
I've tried the array_merge function to merge the data but it doesn't seem to work, I still get the same output.
The array data comprises of the following numbers:
0
0
4249
5126
5128
The code I'm using is as follows:
$player_ids = get_post_meta($post_id,"sp_player", false);
$new_player_ids = array_merge($player_ids);
foreach ( $new_player_ids as $new_player_id ){
print_r ($new_player_id);
Is there another function I've not found yet? Am I doing something wrong here. I'm not sure why one array is being repeated more than once.
Actually guys - figured it out. I had the code within a loop hence it was multiplying the array 3 times.
Fixed it woohoo!!
Thanks for looking

Efficiently Creating Multiple Variables Using apply in R

I have a data frame DF which contains numerous variables. Each variable is present twice because I am conducting an analysis of "couples".
Among others, DF has a series of indicators of diversity :
DF$div1.1, DF$div2.1, .... , DF$divN.1, DF$div.1.2, ..., DF$divN.2
Similarly, it has a series of indicators of another characteristic:
DF$char1.1, DF$char2.1, .... , DF$charM.1, DF$char.1.2, ..., DF$charM.2
Here's a link to an example of DF: http://shorttext.com/5d90dd64
Each time the ".1", ".2" stand for the couple member considered.
My goal:
For each indicator divI and charJ, I want to create another variable DF$divchar that takes the value DF$divI.1 when DF$charJ.1>DF$charJ.2; and DF$divI.2 when DF$charJ.1<DF$charJ.2.
Here is the solution I came up with, it seems somehow very intricate and sometimes behaves in strange ways:
I created a series of binary variables that take the value one if DF$charJ.1>DF$charJ.2. The are stored under DF$CharMax.1.
Here's how I created it:
DF$CharMax.1 <- as.data.frame(
sapply(1:length(nam),
function(n)
as.numeric(DF[names(DF)==names.1[n]]
>DF[names(DF)==names.2[n]])
))
I created the function BinaryExtract:
BinaryExtract <- function(var1, var2, extract) {var1*extract +var2*(1-extract)}
I created the matrix NameFull that contains all the possible combinations of div and char, separated with "YY"
NameFull <- sapply(c("div1",...,"divN")
, function(nam) paste(nam, names(DF$YMax.1), sep="YY")
And then I create all my variables:
DF[, as.vector(NameFull)] <- lapply(as.vector(NameFull), function(e)
BinaryExtract(DF[,paste0(unlist(strsplit(e,"YY"))[1],".1")]
, DF[, paste0(unlist(strsplit(e,"YY"))[1],".1")]
, DF$charMax.1[unlist(strsplit(e,"YY"))[2]]))
My Problem
A. It looks like a very complicated solution for something that simple. What am I missing?
B. Moreover, when I print DF, just typing DF in the command window, I do not see the variables NameFull. They seem to appear with the names of char.
Here's what I get: http://shorttext.com/5d9102c
Similarly, I have tried to change all their names to get rid of the "YY" and it does not seem to work:
names(DF[, as.vector(NameFull)]) <- as.vector(c("div1",...,"divN"), sapply(, function(nam)
paste(nam, names(DF$YMax.1), sep=".")))
When I look at names(DF), I keep getting the old names with the "YY"
However, I do get a result if I explicitly call for them
> DF[,"divIYYcharJ"]
I would really appreciate any suggestion, comment and explanation. I am quite new to R ad was more used to Stata. I feel there is something deeply inefficient here. Thanks

Adding/generating content automatically in Vim

I have a huge list of numbers and I would like to add content on the end of each line. It's something like this:
Before:
123123
123123
13234
124125
12634
5234
After:
123123, 1
123123, 2
13234, 3
124125, 4
12634, 5
5234, 6
A couple of points:
I know that :range s/oldpattern/newpattern/ will substitute the oldpattern by the new one.
I know that for i in range(begin, end) | something | endfor can generate those extra numbers.
However, I don't know if it's possible to combine them to do what I want (or if there's a different way to do it). Does anybody knows how can I add those extra values automatically? I'm quite sure that it's possible using Vim, but I don't know how.
You can do this by visually selecting the area then typing
:s/$/\=', '.(line('.')-line("'<")+1)<CR>
(range is added automatically when you type : from visual mode). Visual mode is needed to get line("'<") thing, if you are fine with typing line number in place of it use any range.
I'd do
:%!nl
:%s/\v^\s*(\d+)\s+(.*)$/\2, \1/g
nl will (by default) skip numbering empty lines
Or as a oneliner
:exec "%!nl"|%s/\v^\s*(\d+)\s+(.*)$/\2, \1/g
:%!awk '{print $0", "NR}'
or
:%!perl -lpe '$_.=", $."'

Resources