Transposing row vector X to get compatible dimensions warning in Scilab - scilab

I am learning to use Scilab, I tried plotting a function wich I know have a discontinuity at a certain value but the plot I got had a non expectable behavior so I tried to plot a very well known function "y=1/x".
I created the "x" vector
x=[-10:1:10];
Then created the "y" function
y=1/x;
And then used the plot command
plot(x,y)
I got the following warning
WARNING: Transposing row vector X to get compatible dimensions
And my plot is a straight line, I don't know what I'm doing wrong.

Take care: 1/x compute some thing like 1*pinv(x) not the array [1/x(1),1/x(2),...]. to obtain the previous result use 1 ./x for element wise disvision.

Well, try typing x and y into the consol, to see, how your variables look like:
-->x
x =
column 1 to 12
- 10. - 9. - 8. - 7. - 6. - 5. - 4. - 3. - 2. - 1. 0. 1.
column 13 to 21
2. 3. 4. 5. 6. 7. 8. 9. 10.
-->y
y =
- 0.0129870
- 0.0116883
- 0.0103896
- 0.0090909
- 0.0077922
- 0.0064935
- 0.0051948
- 0.0038961
- 0.0025974
- 0.0012987
0.
0.0012987
0.0025974
0.0038961
0.0051948
0.0064935
0.0077922
0.0090909
0.0103896
0.0116883
0.0129870
So x is a row array, and y is a column array, that's why scilab is complaining about incompatible dimensions. To remove the warning, you must transpose one of your arrays, to make them identical in dimensions. You can do it many places, e.g:
y=1/x';
or
plot(x',y);
or
plot(x,y');
Note: in Scilab 5.4.x and earlier versions there was no such warning, Scilab silently transposed one of the arrays.

Related

R: How to interpret square brackets with forms like y[i : j - k]

Can you help me understand how R interprets square brackets with forms such as y[i:j - k]?
dummy data:
y <- c(1, 2, 3, 5, 7, 8)
Here's what I do understand:
y[i] is the ith element of vector y.
y[i:j] is the ith to jth element (inclusive) of vector y.
y[-i] is vector y without the first i elements. etc. etc.
However, what I don't understand is what happens when you start mixing these options, and I haven't found a good resource for explaining it.
For example:
y[1-1:4]
[1] 5 7 8
So y[1-1:4] returns the vector without the first three elements. But why?
and
y[1-4]
[1] 1 2 5 7 8
So y[1-4] returns the vector without the third element. Is that because 1-4 = -3 and it's interpretting it the same as y[-3]? If so, that doesn't seem consistent with my previous example where y[1-1:4] would presumably be interpretted as y[0:4], but that isn't the case.
and
y[1:1+2-1]
[1] 2
Why does this return the second element? I encountered this while I was trying to code something along the lines of: y[i:i + j - k] and it took me a while to figure out that I should write y[i:(i + j - k)] so the parenthesis captured the whole of the right-hand-side of the colon. But I still can't figure out what logic R was doing when I didn't have those brackets.
Thanks!
It's best to look closer at precedence and the integer sequences you use for subsetting. These are evaluated before subsetting with []. Note that - is a function with two arguments (1, 1:4) which are evaluated beforehand and so
> 1-1:4
[1] 0 -1 -2 -3
Negative indices in [] mean exclusion of the corresponding elements. There is no "0" element (and so subsetting at 0 returns an empty vector of the present type -- numeric(0)). We thus expect y[1-1:4] to drop the first three elements in y and return the remainder.
As you write correctly y[1-4] is y[-3], i.e. omission of the third element.
Similar as above, in 1:1+2-1, 1:1 evaluates to a one-element vector 1, the rest is simple arithmetic.
For more on operator precedence, see Hadley's excellent book.

matrix operations on matrix with "missing" elements

I'm trying to analyse some experimental in a matrix and I'm having some issues.
For example I'd like to scale the columns of a matrix so that the first row of each column is 1.
I'd like to do it in the neat/clean julia way that I'm now starting to learn but I'm struggling to find a good solution.
The problem comes from the fact that each column is the result of some experimental test, and they have different lengths. I've "fixed" this by creating the matrix in excel, adding a missing in the empty cells at the bottom of the column and then copy pasting it in julia. I take this is probably not the best way to deal with the issue?
Example: (normal matrices are much bigger though)
A=[1 2 3
4 5 6
missing missing 9]
After that, I'd like to do some analysis, one of which is scaling the matrix so that the first row is = [1 1 1...1]. I tried both map
map((x,y)->x./y,A[2:end,:],A[1,:])
but it seems to apply the top row the the first N elements of the first column only.
Alternatively I tried with mapslices but I'm getting the following error MethodError: Cannot `convert` an object of type Missing to an object of type Float64
I have the feeling I'm missing something and my googlefoo is failing me... any help is much appreciated!
PS: Apologies if I missed some already answered question or if I missed some guideline, I'll try to improve my question if needed. It's the first time I post here!
I'm not sure what your first question is, it seems hard to answer without knowing what the data you're processing it looks like.
Your second question if I understand correctly should be as simple as:
julia> A ./ A[1, :]'
3×3 Matrix{Union{Missing, Float64}}:
1.0 1.0 1.0
4.0 2.5 2.0
missing missing 3.0
Edit to add:
Whether a matrix is or isn't a good idea here depends on the wider context, but if you have some vectors of numbers of different lengths, you can just put them in a vector of vectors rather than a matrix, which means they don't all have to have the same length:
julia> x = rand(3); y = rand(5);
julia> A = [x, y]
2-element Vector{Vector{Float64}}:
[0.2654489138174001, 0.8598585826482341, 0.43527866751212607]
[0.4702376843007643, 0.7890927390349933, 0.6073796489306595, 0.9178238662871376, 0.5917433487576529]
julia> A ./ first.(A)
2-element Vector{Vector{Float64}}:
[1.0, 3.2392620119731323, 1.6397831931290188]
[1.0, 1.6780721013637205, 1.2916439264833126, 1.9518296745015802, 1.2583920185758093]

Why doesn't this Scilab program of finding the determinant recursively work?

I am trying to find the determinant of an $N\timesN$ matrix. Here's my code:
clc
function determinant=take_detm(A)
order=sqrt(length(A))
disp(order)
if order==2 then
determinant=A(1,1)*A(2,2)-A(1,2)*A(2,1);
else
s=0
for i=1:order
s=s+((-1)^(i+1))*A(1,i)*take_detm(A(:,i)=[]);//deleting 1st row and a column in the recursive call
end
determinant=s
end
endfunction
matr=input("Enter a matrix")
printf (string(take_detm(matr)))
Here's the problem: When I run the code and input a matrix as: [1 2 3 4;5 6 7 8;9 10 11 12;13 14 15 16] the console prints 4 (the order) and the program hangs. I get that rolling blue ring of Windows 7 and after some time a message which says that Scilab 6.0.1 has stopped working. Is there any issue with the algorithm or is it something else?
PS-Beginner level
The problem is due to the A(:,i)=[] instruction. assigning [] only works for a set of full rows or a set of full lines, so your instruction simply removed the ith column of the A matrix (the result being a rectangular matrix)
You can fix the problem with
Ai=A(2:order,[1:i-1 i+1:order])//deleting 1st row and column i
s=s+((-1)^(i+1))*A(1,i)*take_detm(Ai); //recursive call
Note however that the Scilab det function is much more precise and efficient
Okay, so I am confident I get this, hence answering my own question.
When you want to remove a row OR a column in Scilab, you can assign it to []. The following example illustrates how this works.
Consider the matrix
A=[1 2 3 4; 5 6 7 8; 9 10 11 12; 13 14 15 16]
which prints in the console as
A =
1. 2. 3. 4.
5. 6. 7. 8.
9. 10. 11. 12.
13. 14. 15. 16.
If you want to remove the first row, the command is
A(1,:)=[]
A =
5. 6. 7. 8.
9. 10. 11. 12.
13. 14. 15. 16.
You simply assign the first row to the empty matrix. Similarly if you wanted to remove the 2nd column, you assign it to empty matrix:
A(:,2)=[]
A =
5. 7. 8.
9. 11. 12.
13. 15. 16.
(Note that the operation is performed on the updated matrix--i.e the 1st row removed)
But if you want to remove the 1st row and the 2nd column, you can't write:
A(1,2)=[]
Scilab says:
Submatrix incorrectly defined.
Here is an alternate solution using assignment to the empty matrix:
General idea: We perform 2 operations one by one: deleting the 1st row and then the ith column.
Posting code for just the else part:
else
s=0
first_row_removed=A //taking a backup of A and then...
first_row_removed(1,:)=[] //...removing the 1st row
for i=1:order
column_i_removed=first_row_removed //taking a backup of the 1st-row-removed matrix...
column_i_removed(:,i)=[] //... and then deleting column i
s=s+((-1)^(i+1))*A(1,i)*take_detm(column_i_removed); //recursive call
end
determinant=s
end //of else
An important thing to note is that performing the assignment to the empty matrix makes changes in the original matrix itself. Hence for every iteration of the for loop, we must make sure that we perform remove-ith-column operation on the 1st-row-removed matrix and not on the matrix which had its ith column deleted in the previous for loop iteration.
Hence the line
column_i_removed=first_row_removed
must be inside the for loop.

Compare cell against series of cell pairs

I'm trying to make a LibreOffice spreadsheet formula that populates a column based on another input column, comparing each input with a series of range pairs defined in another sheet and finally outputting a symbol based on matched criteria. I have a series of ranges that specify a - output, and another series that corresponds to +, but not all inputs will fall into a category. I am using this trinary output later for another expression, which I already have in place.
My question becomes: how can I test input against each range pair without spelling out the cell coordinates for each individual cell (ie OR(AND(">= $A$1", "< $B$1"), AND(">=$A$2", "<$B$2"), ...))? Ideally I could just specify an array to compare against like $A$1:$B$4. Writing it in a python macro would work, too, since I don't plan on sharing this file.
I wrote a really quick list comp in python to illustrate what I'm after. This snippet would be one half, such as testing - qualification, and these values may be fed into a condition that outputs the symbol:
>>> def cmp(f, r):
... return r[0] <= f < r[1]
>>> f = (1, 2, 3)
>>> ranges = ((2, 5), (4, 6), (3, 8))
>>> [any([cmp(i, r) for r in ranges]) for i in f]
[False, True, True]
Here is a small test example with real input and real ranges.
Change the range pairs so that they are in two columns starting from A13. Be sure that they are in sorted order (Data -> Sort).
A B C
~~~~~~~~ ~~~~~~~~ ~
145.1000 145.5000 -
146.0000 146.4000 +
146.6000 147.0000 -
147.0000 147.4000 +
147.6000 148.0000 -
440.0000 445.0000 +
In each row, specify whether it is negative or positive. To do this, I entered the following formula in C13 and filled down. If the range pairs are not consistent enough then enter values for C13 and below manually.
=IF(ISODD(ROW());"-";"+")
Now, enter the following formula in cell C3 and fill down.
=IFNA(IF(
VLOOKUP(A3;A$13:C$18;2;1) >= A3;
VLOOKUP(A3;A$13:C$18;3;1);
"None");"None")
The formula finds the closest pair and then checks if the number is inside that range or not. For better testing, I would also suggest using 145.7000 as input, which should result in no shift if I understood the question correctly.
The results in column C:
-
+
None
None
Documentation: VLOOKUP, IFNA, ROW.
EDIT:
The following formula produces correct results for the example data you gave, and it works for anything between 144.0 and 148.0.
=IFNA(VLOOKUP(A3;A$13:C$18;3;1); "None")
However, 150.0 produces - and 550.0 produces +. If that is not what you want, then use the formula above that has two VLOOKUP expressions.

Return 0 for 'subscript out of bounds error'

Is there a simple way to deal with the “subscript out of bounds” error. I’d like to return 0 where this occurs, instead of having the error interrupt the code.
I understand the nature of the error in my context and it’s a perfectly legitimate finding that I'd like to report:
• I’m capturing the difference between two data items.
• So if e.g. there are 0 instance of case "a" (which might be where the difference is 0) then I get the subscript out of bounds error when looking up the matrix row name equal to “a”, whereas I’d like to report this finding as 0.
In the following simplified example, both CASE 1 and CASE 2 occur across my various matrices, but CASE 2 returns the 'subscript out of bounds' error.
# CASE 1
distribution <- matrix(c(1:12), nrow=12, ncol=1)
rownames(distribution) <- letters[1:12]
distribution["a",]
# CASE 2
distribution <- matrix(c(1:11), nrow=11, ncol=1)
rownames(distribution) <- letters[2:12]
distribution["a",]
and want to report the finding...
distribution["a",]
...for each of my matrices.
Something equivalent to the iferror formula in excel is what I'm after I guess.
Any thoughts / alternative suggestion to the problem are much appreciated.

Resources