I think the answer is probably 'no' as from what I can tell maths libraries don't seem to handle null, but what I'd like to have is to be handle null in these scenarios:
x=1
(y not defined)
z = sum(x, y)
with eval() ideally giving:
z=1
However, this throws an exception, as y is not defined.
In effect I'm defaulting 'y' to zero in that example, and that won't work in all scenarios.
So, what I suppose I'm asking is, is there an in-built way to define a default for a variable if it's not assigned a value?
If not, I'm assuming that this would be possible by writing a custom function. If someone could confirm this, I'd really appreciate it.
Thanks :-).
Ok - I was looking through the release notes for v4 and saw it talking about the constants 'null, undefined' (and others). So, in order to solve this I have to define a variable as undefined (probably should have known this!).
(Note: I suspect these constants are available in previous version too.)
Then combined with a 'default' custom function I can get what I wanted:
x=1
y = null
z = sum(x, def(y, 0))
z=1
where 'def' is defined and imported as below (making use of 'lodash'):
var customFunctions = {
def: function (value, defaultValue) {
return !_.isNil(value) ? value : defaultValue;
}
};
math.import(customFunctions);
BOSH!
Related
I am currently programming in BCPL for an OS course and wanted to write a simple is_digit() function for validation in a program of mine.
A code snippet of my current code follows:
let is_digit(n) be {
if ((n >= '0') /\ (n <= '9')) then
resultis true;
}
I am aware that BCPL has no notion of types, but how would I be able to accomplish this sort of thing in the language?
Passing in a number yields a false result instead of the expected true.
is_digit() is a function returning a value, rather than a routine, so should use = VALOF rather than BE. Otherwise, the code is OK.
let is_digit(n) = valof {
.....
resultis true
}
Functions that return values should be using valof rather than be, the latter (a routine rather than a function) can be called as a function but the return value you get back from it will be undefined(a).
In addition, you should ensure you return a valid value for every code path. At the moment, a non-digit will not execute a RESULTIS statement, and I'm not entirely certain what happens in that case (so best to be safe).
That means something like this is what you're after, keeping in mind there can be implementation variations, such as & and /\ for and, or {...} and $(...$) for the block delimiters - I've used the ones documented in Martin's latest manual:
LET is_digit(n) = VALOF {
RESULTIS (n >= '0') & (n <= '9')
}
(a) Since Martin Richards is still doing stuff with BCPL, this manual may help in any future questions (or see his home page for a large selection of goodies).
From the documentation, we see the following example:
g = gallery('integerdata',3,[15,1],1);
x = gallery('uniformdata',[15,1],9);
y = gallery('uniformdata',[15,1],2);
A = table(g,x,y)
func = #(x, y) (x - y);
B = rowfun(func,A,...
'GroupingVariable','g',...
'OutputVariableName','MeanDiff')
When the function func is applied to A in rowfun how does it know that there are variables in A called x and y?
EDIT: I feel that my last statement must not be true, as you do not get the same result if you did A = table(g, y, x).
I am still very confused by how rowfun can use a function that does not actually use any variables defined within the calling environment.
Unless you specify the rows (and their order) with the Name/Value argument InputVariables, Matlab will simply take column 1 as first input, column 2 as second input etc, ignoring eventual grouping columns.
Consequently, for better readability and maintainability of your code, I consider it good practice to always specify InputVariables explicitly.
I have a problem with If statement in OpenScad.
I have 4 variables
a=20;
b=14;
w=1;
c=16;
I want to check witch number is bigger a or b.
And after depending who is smaller to take the value of smaller variable(in our case b < a) and to make a simple operation with c variable ( c=b-w).
I tried like this but it doesn't work.
a=20;
b=14;
w=1;
c=16;
if(a>b)
{
c=b-w;
}
if (a<b)
{
c=a-w;
}
if (a==b)
{
c=a-w;
}
It seems logic, but in openscad as I understood you can't change the value of variable inside a If statement. What trick can I use in order to get my goal.
Thank you!
in the 3. leg you confused the assignment-operator „=“ with the equal-operator „==“ (correct if (a==b)).
in your 3. leg you do the same as in the 2., so you could handle both as an „else“-leg.
Correct: assignment is not allowed in if-statement. In openscad you can use the ? operator instead:
c = a > b ? b-w : a-w;
After = follows the condition. The statement after the ? becomes the value if the condition is true, and the statement after the : becomes the value if the condition is false. Nested conditions are possible, e.g. your conditions:
c = a > b ? b-w : (a < b ? a-w : a-w);
More information in the documentation.
OpenSCAD's variable assignment is different. You can only assign variables inside a bracket. So c = b - w will only be assigned inside the if bracket. Outside if this bracket it will still be 16. Don't ask me why. You can read more in the Documentation of OpenSCAD.
c = min(c,min(a,b)/2-w);
this also solve the problem )
I have the following scenario. In myClass.m I have defined
classdef myClass
...
methods
function y = foo(this, x)
...
end
end
end
Then I execute
obj = myClass();
nargin(#obj.foo)
and get as a result -1 while I would expect 1. The function nonetheless accepts only one argument.
I actually want to pass the handle to another function (in which I don't have access) which checks the number of arguments and I want the check nargin(f)==1 to succeed. Is there a way to do that?
PS
I know that if I define the method as static I will get the correct result by calling nargin(#(x)Test.foo) but the method accesses class variables.
Even though this question got answered and accepted, I think it is worth to show a working approach, which works even without creating an instance of the class. Reference to metaclass: https://ch.mathworks.com/help/matlab/ref/metaclass.html
metaClass = ?myClass
numArgIn = zeros(length(metaClass.MethodList), 1);
names = strings(length(metaClass.MethodList), 1);
for i=1:length(metaClass.MethodList)
names(i) = string(metaClass.MethodList(i).Name);
numArgIn(i) = numel(metaClass.MethodList(i).InputNames);
end
disp(numArgIn(names=="foo"))
When you create a folder with the class and some modules, you can use the following one-liner notation:
nargin('#myClass/foo.m')
In the latter example, the file ending can be removed without effect.
I can no longer verify the validity of this answer. See more recent answer(s) and comments.
Original answer
I fixed the problem by defining my own wrapper something like
function y = mywrapper(f, x)
%MYWRAPPER nargin(#(x)mywrapper(f, x)) is 1 as it should be
y = f(x);
end
I realised that nargin(#(x)#obj.foo), also does what I wanted
I am working on a project and have many functions to create and they do need lots of debugging so instead of just hitting the run button i have to go to command window and give a function call.
does MATLAB support assignment of default values to input arguments like python does?
In python
def some_fcn(arg1 = a, arg2 = b)
% THE CODE
if you now call it without passing the arguments it doesn't give errors but if you try the same in MATLAB it gives an error.
For assigning default values, one might find it easier to manage if you use exist function instead of nargin.
function f(arg1, arg2, arg3)
if ~exist('arg2', 'var')
arg2 = arg2Default;
end
The advantage is that if you change the order of arguments, you don't need to update this part of the code, but when you use nargin you have to start counting and updating numbers.
If you are writing a complex function that requires validation of inputs, default argument values, key-value pairs, passing options as structs etc., you could use the inputParser object. This solution is probably overkill for simple functions, but you might keep it in mind for your monster-function that solves equations, plots results and brings you coffee. It resembles a bit the things you can do with python's argparse module.
You configure an inputParser like so:
>> p = inputParser();
>> p.addRequired('x', #isfinite) % validation function
>> p.addOptional('y', 123) % default value
>> p.addParamValue('label', 'default') % default value
Inside a function, you would typically call it with p.parse(varargin{:}) and look for your parameters in p.Results. Some quick demonstration on the command line:
>> p.parse(44); disp(p.Results)
label: 'default'
x: 44
y: 123
>> p.parse()
Not enough input arguments.
>> p.parse(Inf)
Argument 'x' failed validation isfinite.
>> p.parse(44, 55); disp(p.Results)
label: 'default'
x: 44
y: 55
>> p.parse(13, 'label', 'hello'); disp(p.Results)
label: 'hello'
x: 13
y: 123
>> p.parse(88, 13, 'option', 12)
Argument 'option' did not match any valid parameter of the parser.
You can kind of do this with nargin
function out = some_fcn(arg1, arg2)
switch nargin
case 0
arg1 = a;
arg2 = b;
%//etc
end
but where are a and b coming from? Are they dynamically assigned? Because that effects the validity of this solution
After a few seconds of googling I found that as is often the case, Loren Shure has already solved this problem for us. In this article she outlines exactly my method above, why it is ugly and bad and how to do better.
You can use nargin in your function code to detect when no arguments are passed, and assign default values or do whatever you want in that case.
MathWorks has a new solution for this in R2019b, namely, the arguments block. There are a few rules for the arguments block, naturally, so I would encourage you to learn more by viewing the Function Argument Validation help page. Here is a quick example:
function ret = someFunction( x, y )
%SOMEFUNCTION Calculates some stuff.
arguments
x (1, :) double {mustBePositive}
y (2, 3) logical = true(2, 3)
end
% ...stuff is done, ret is defined, etc.
end
Wrapped into this is narginchk, inputParser, validateattributes, varargin, etc. It can be very convenient. Regarding default values, they are very simply defined as those arguments that equal something. In the example above, x isn't given an assignment, whereas y = true(2, 3) if no value is given when the function is called. If you wanted x to also have a default value, you could change it to, say, x (1, :) double {mustBePositive} = 0.5 * ones(1, 4).
There is a more in-depth answer at How to deal with name/value pairs of function arguments in MATLAB
that hopefully can spare you some headache in getting acquainted with the new functionality.