OCTAVE: Checking existence of an element of a cell array - octave

I am using Octave 4.0.0.
I define A{1, 1} = 'qwe', but when I check existence of A{1, 1}, as in
exist("A{1,1}")
or
exist("A{1,1}", "var")
it returns 0.
How can I check its existence?

To check if an array has element say 3, 5, you need to verify that the array has at least 3 rows and 5 columns:
all(size(A) >= [3, 5])
You can of course check if variable A exists at all before-hand, and also is a cell array. A complete solution might be something like
function b = is_element(name, varargin)
b = false;
if ~evalin(['exists("' name '")'], 'caller')
return;
end
if ~strcmp(evalin(['class(' name ')'], 'caller'), 'cell')
return;
end
if evalin(['ndim(' name ')'], 'caller') ~= nargin - 1
return;
end
b = all(evalin(['size(' name ')'], 'caller') >= cell2mat(varargin))
endfunction
This function accepts a variable name and the multi-dimensional index you are interested in. It returns 1 if the object exists as a cell array of sufficient dimensionality and size to contain the requested element.

Related

Why one element of SubString Vector can not be tested into conditional evaluation if (Julia)?

I want to create a function in which, first, it filters one element of a dataframe in Julia. Second, it tests if the element is "missing". If the answer is rue, it return the value "0.0". My issue is that the control evaluation "if" does not work and I don t know why. If the element is "String" the control evaluation works, however, the element is a 1-element Vector{SubString{String}}: after filtering; thus, the control evaluation does not work. I would like to know why and it is possible to turn the vector element into a string object.
Note: "isequal", '==', '===' do not work either.
For example:
example_ped = DataFrame(animal = collect(1:1:11),
sire = [fill(0,5); fill(4,3); fill(5,3)],
dam = [fill(0,4); fill(2,4); fill(3,3)])
CSV.write("ped_example.txt",example_ped, header=true,delim='\t')
pedi = CSV.read("ped_example.txt",delim = '\t', header=true, missingstrings=["0"], DataFrame)
pedi[!,1]=strip.(string.(pedi[!,1]))
pedi[!,2]=strip.(string.(pedi[!,2]))
pedi[!,3]=strip.(string.(pedi[!,3]))
Part of the function
function computAddRel!(ped,animal_1,animal_2)
elder,recent = animal_1 < animal_2 ? (animal_1,animal_2) : (animal_2,animal_1)
sireOfrecent = ped.sire[ped.animal.==recent]
damOfrecent = ped[ped.animal.==recent,"dam"]
if elder==recent
f_inbreed = (sireOfrecent=="missing" || damOfrecent=="missing") ? 0.0 : 0.5*computAddRel!(ped,sireOfrecent,damOfrecent)
adiv = 1.0 + f_inbreed
return adiv
end
end
if the animal_1 and animal_2 are equal to 5
julia> sireOfrecent = pedi.sire[pedi.animal.==recent]
1-element Vector{Union{Missing, Int64}}:
missing
However, the control evaluation is false
julia> sireOfrecent=="missing"
false
julia> isequal(sireOfrecent,"missing")
false
Thank in advance for your time.
You should write:
ismissing(only(sireOfrecent))
The meaning of this:
only checks if you picked exactly one row (if not - you will get an error, as then there is ambiguity; if yes - you extract out the element from an array)
ismissing is a function that you should use to check if some value is missing.
Here are some examples:
julia> x = [missing]
1-element Vector{Missing}:
missing
julia> only(x)
missing
julia> ismissing(only(x))
true
julia> only([1, 2])
ERROR: ArgumentError: Collection has multiple elements, must contain exactly 1 element
julia> ismissing(only([1]))
false

Is there a single Apps Script function equivalent to MATCH() with TRUE?

I need to write some functions that involve the same function as the Sheets function MATCH() with parameter 'sort type' set to TRUE or 1, so that a search for 35 in [10,20,30,40] will yield 2, the index of 30, the next lowest value to 35.
I know I can do this by looping over the array to search, and testing each value against my search value until a value greater than the search value is found, but it seems to me there must be a shorthand way of doing this. We don't have to do this when seeking an exact value; we can just use indexOf(). I was surprised when I first learned that indexOf() does not have a parameter for search type, but can only return a -1 if an exact value is not found.
Is there no function akin to indexOf() that will do this, or is it actually necessary to loop over the array every time you need to do this?
Probably you're looking for the array.find() method. The impelentation could be something like this:
var arr = [10,20,30,40]
// make a copy of the array, reverse it and do find with condition
var value = arr.slice().reverse().find(x => x < 35)
console.log(value) // output --> 30 (first element less than 35 in the reversed array)
var index = arr.indexOf(value)
console.log(index) // output --> 2 (index of the element in the original array)
https://www.w3schools.com/jsref/jsref_find.asp
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
There is another method array.findIndex(). Probably you can use it as well:
var arr = [10,20,30,40]
// find more or equal 35 and return previous index
var index = arr.findIndex(x => x >= 35) - 1
console.log(index) // output --> 2
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
Try this:
function lfunko(tgt = 35) {
Logger.log([10,20,30,40].reduce((a,c,i) => { a.r = (a.x >= c)? i:a.r;return a;},{x:tgt}).r)
}

Using 2 different outputs of 'return' of a function in separate elements of a plot

I am drawing a plot of voltage per time. For the voltage values, I want the values to be evaluated by a 'scaling' function which converts the values from volts to kilovolts if the biggest element is higher than 1000 volts (11000 volts to 11 KILOvolts).
This function is supposed to return 2 separate outputs; one for (new) values of voltage and one for the unit. The values are fed into the y axis values of the plot and the unit is given to the labeling line of that axis. For example:
import numpy as np
time = np.array([0, 1, 2, 3])
system_voltage1 = np.array([110, 120, 130, 150])
system_voltage2 = np.array([11000, 12000, 13000, 15000])
scaling_function(input)
if np.amax(input) < 1000:
output = input/1
Voltage_label = 'Voltage in Volts'
if np.amax(input) > 1000:
output = input/1000
Voltage_label = 'Voltage in KILOVolts'
return(output, Voltage_label)
fig14 = plt.figure(figsize=(16,9))
ax1 = fig14.add_subplot(111)
l1, = ax1.plot(time, scaling_function(system_voltage), color='r')
ax1.set_xlabel("time in second", color='k')
ax1.set_ylabel(Voltage_label, color='k')
Now, I am having trouble, calling this function properly. I need the function to only receive the output for scaling_function(system_voltage), and receive Voltage_label in ax1.set_ylabel(Voltage_label, color='k'). Now:
A) My problem: I don't know how to write the code so only the first output is received and used for scaling_function(system_voltage) , and the second element for the labeling line.
B) Something I tried but didn't work:Voltage_label does not recognize the value of voltage_label from scaling_function, as it is located in an outer loop than the function. I mean, I cannot access voltage_label as its value is not globally assigned.
Can anyone help me with this?
y,l = scaling_function(system_voltage)
l1, = ax1.plot(time, y, color='r')
ax1.set_xlabel("time in second", color='k')
ax1.set_ylabel(l, color='k')

Vectorization of cell-array element manipulation

I have a 1xN dimensional cell-array containing matrices of dimension AxB, where A > 0 and B > 2. I want to extract the second and third column of each matrix and create a new cell-array containing these new matrices.
I know I can do this:
newcell = cell(size(oldcell));
for i = 1:size(oldcell,2)
newcell{i} = oldcell{i}(:, [2, 3]);
endfor
But I'm wondering if the loop can be avoided by further vectorization?
I figured it out. This can be done with cellfun(), with the option UniformOutput set to false (the default is true).
newcell = cellfun(#(x) x(:, [2, 3]), oldcell, 'UniformOutput', false);
The reason this doesn't work with UniformOutput=true is that cellfun() then expects the outputs to be scalar, which they are not in this case.

function to return index of largest neighbor

F# function
Problem:
given a list of items e.g.:
["5";"10";"2";"53";"4"]
and a Search Index, I require a function such that it compares the current given index against its neighbor, returning the largest index
Example:
Given Index 1 will return Index value 2 (because 10 is greater than 5).
Given Index 4 will return Index 4 (because 53 is greater than 4)
Currently this is my function. It does not compile:
let GetMaxNode (x:Array) Idx = if x.[Idx] > x.[Idx+1] then Idx else If x.[Idx] < x.[Idx+1] then Idx+1
The errors I'm getting for all the x' are:
The field, constructor or member 'Item' is not defined (FS0039)
And also the second If:
The value or constructor 'If' is not defined (FS0039)
I suspect I'm still thinking in a procedural way, I was thinking about using pattern matching, however I was not confident enough with the syntax to try it.
Please can you also explain the answer as well, as I'm trying to learn F#, just the solution will not help me much.
Here's some code based on yours:
let GetMaxNode (x:_[]) idx =
if x.[idx] > x.[idx+1] then
idx
elif x.[idx] < x.[idx+1] then
idx+1
else
idx // same, return this one
The main changes are
to declare an array type, say <typename> []. In this case, we don't care about the type, so I use _ as a "don't care, please go infer the right thing for me" type variable.
"else if" is spelled elif in F#
need an else case for if equal
It is difficult to write solution to your problem in a functional style, because your problem is defined in terms of indices - when using functional data structures, such as lists, you don't usually refer to the elements by their index.
A functional version of your question would be, for example, to create a list that contains true when the element at the current position is larger than the next one and false when it is smaller. For your data this would give:
let data = [ 5; 10; 2; 53; 4 ]
let res = [ false; true; false; true; ] // no item to compare '4' with
This can be solved quite nicely using a recursive function that walks through the list and pattern matching (because pattern matching works much better with functional lists than with arrays)
let rec getMaxNodes data =
match data with
// list has at least two elements and current is larger
| current::next::other when current >= next ->
// process the rest of the list
let rest = (getMaxNodes (next::other))
// return 'true' followed by recursively processed rest of the list
true::rest
// list has at least two elements and current is smaller
| current::next::rest ->
// same as the previous case, but we return false
false::(getMaxNodes (next::rest))
| _ ->
// one element (so we cannot compare it with the next one)
// or empty list, so we return empty list
[]
getMaxNodes data
Here's the pattern matching version of Brian's answer.
let GetMaxNode (x:_[]) idx =
match idx with
| idx when x.[idx] > x.[idx+1] -> idx
| idx when x.[idx] < x.[idx+1] -> idx + 1
| idx -> idx // same, return this one
You may also see a syntax shortcut as you look at more F# code. The below code is functionally exactly the same as the above code.
let GetMaxNode (x:_[]) = function
| idx when x.[idx] > x.[idx+1] -> idx
| idx when x.[idx] < x.[idx+1] -> idx + 1
| idx -> idx // same, return this one
Whenever you start talking about indices, you are best sticking with Arrays or ResizeArrays; F# lists are not well-suited for operations on indices since they are singly-linked head to tail. That being said, it is not too difficult to write this algorithm in a purely functional way by moving through the list using a recursive loop and keeping track of the current index and current element.
let find elements index =
//a local tail-recursive function hides implementation details
//(cur::tail) is a pattern match on the list, i is the current index position
let rec loop (cur::tail) i =
if i = index then //when the current index matches the search index
if cur >= tail.Head then i //compare cur to tail.Head (which is next)
else (i+1)
else loop tail (i+1) //else continue
loop elements 0 //the entry point of loop and our return value
Use a list of ints instead of strings to get the results you expect (since "10" is actually less than "5"):
> let x = [5;10;2;53;4];;
> find x 0;;
val it : int = 1
> find x 1;;
val it : int = 1
> find x 2;;
val it : int = 3
> find x 3;;
val it : int = 3