Writing a predict() function for the Smatr package - prediction

How to write a predict() function for the Smatr package (specifically for the sma command)?

Related

Using unittest with own matlab toolbox

I inherited a code base in matlab, which I like to put under unittest with the matlab.unittest framework.
To make the code base more robust against arbitrary addpath of my users, I have put most of the code into +folders like a toolbox. So the general layout is:
+folder1/file1.m
+folder1/runtestsuite.m
+folder1/unittest_data/file1_testdata.mat
+folder1/+folder2/file2.m
+folder1/+folder2/unittest_data/file2_testdata.mat
...
and updated all internal references with the correct import statements.
Now, I like to add a unittest for file1.m. However if I put a file in +folder1/file1_test.m file1.m seems not to be visible.
Here is my example code of file1_test.m
classdef file1_test < matlab.unittest.TestCase
properties
path
end
methods(TestMethodSetup)
function setunittestdatapath(testCase)
p = mfilename('fullpath');
[directory,~,~]=fileparts(p);
testCase.path = fullfile(directory,'unittest_data');
end
end
methods (Test)
function file1_input(testCase)
%import folder1.file1
testdata = load(fullfile(testCase.path),'file1_testdata.mat');
result = file1(testdata.input);
testCase.verifyEqual(result, testdata.output);
end
end
end
If I uncomment the import statement the unittest works fine. So currently I have to add all import statements to each individual test, which I like to avoid. Is there a more elegant way for doing something like this?
I tried importing it at the beginning of the file, although matlab complains "Parse error at CLASSDEF: usage might be invalid MATLAB syntax." this also works. So what is the correct and most pragmatically way for doing something like this?
import statements only apply to the local scope of where they are used so if you want a function to be able to not use the full-qualified name, then you'll have to add the import statement to each function separately.
The import list scope is defined as follows:
Script invoked from the MATLAB® command prompt — Scope is the base MATLAB workspace.
Function, including nested and local function — Scope is the function and the function does not share the import list of the parent function. If the import list is needed in a MATLAB function or script and in any local functions, you must call the import function for each function.
For unit tests though, I would argue that it is probably best to use the fully-qualified function name every time (rather than relying on import) so that it's clear to the user what you're testing.
result = folder1.file1(testdata.input)
Currently import statements in MATLAB have function scope as mentioned in the answer by Suever.
However, I often use local functions as a workaround to mimic a file level import:
classdef file1_test < matlab.unittest.TestCase
properties
path
end
methods(TestMethodSetup)
function setunittestdatapath(testCase)
p = mfilename('fullpath');
[directory,~,~]=fileparts(p);
testCase.path = fullfile(directory,'unittest_data');
end
end
methods (Test)
function file1_input(testCase)
%import folder1.file1
testdata = load(fullfile(testCase.path),'file1_testdata.mat');
result = file1(testdata.input);
testCase.verifyThat(result, IsEqualTo(testdata.output));
end
end
end
% Include file level "import" functions below
function f = file1(varargin)
f = folder1.file1(varargin{:});
end
function c = IsEqualTo(varargin)
c = matlab.unittest.constraints.IsEqualTo(varargin{:});
end
Note in this example I "imported" both your source code as well as some of the test framework source code in order to use the literate form of verifyEqual using verifyThat. Note this is the same functional behavior, but in general there exists more functionality with the constraints than with the qualification methods so this may be helpful to you at some point.

Why can you import a package *after* using its content in a function?

I'm on MATLAB R2014b and have a question that I will illustrate with the following example.
MWE can be made as follows or download it as a .zip file here.
Create a package folder +test on your path with four function files in it:
+test
a.m
b.m
c.m
d.m
Content of a.m:
function a
disp 'Hello World!'
Content of b.m:
function b
a
If you run b from the command line, you will have to import the test package first (import test.*) or run test.b.
Running b will result in an error, since the scope of function b doesn't contain function a. We must import it before it can be used. For this I've created c.m:
function c
import test.*
a
Now running c works fine.
Now my question. If I change c.m to (saved in d.m):
function d
a
import test.*
I.e. the import command is issued after the call to package function a. Running d still works just fine, as if the position of the import command in d.m does not matter. The import appears to have occurred before the call to function a, which in d.m happens on the line before the import.
Why does this happen. Is this the intended behaviour and what are its uses? How and in what order does MATLAB read a .m file and process it? And more off-topic, but in general: how is importing packages handled in different languages compared to MATLAB, does the order of commands matter?
My preemptive conclusion based on the comments: It is probably best practice to only use the import function at or near the beginning of MATLAB code. This makes clearly visible the imported content is available throughout the entire element (e.g. function). It also prevents the incorrect assumption that before the import, the content is not yet available or refers to a different thing with the same name.
MATLAB performs static code analysis prior to evaluating a function in order to determine the variables/functions used by that function. Evaluation of the import statements is part of this static code analysis. This is by design because if you import a package and then use it's functions, MATLAB needs to know this during the static code analysis. As a result, regardless of where you put the import statement within your function, it will have the same effect as if it were at the beginning of the function.
You can easily test this by looking at the output of import which will list all of the current imported packages.
+test/a.m
function a(x)
disp(import)
import test.*
end
test.a()
% test.*
This is why the documentation states to not put an import statement within a conditional.
Do not use import in conditional statements inside a function. MATLAB preprocesses the import statement before evaluating the variables in the conditional statements.
function a(x)
disp(import)
if x
import test.*
else
import othertest.*
end
end
test.a()
% test.*
% othertest.*
The only way to avoid this behavior is to allow the static code analyzer to determine (without a doubt) that an import statement won't be executed. We can do this by having our conditional statement be simply a logical value.
function a()
disp(import)
if true
import test.*
else
import othertest.*
end
end
test.a()
% test.*
As far as importing compared to other languages, it really depends on the language. In Python for example, you must place the import before accessing the module contents. In my experience, this is the typical case but I'm sure there are many exceptions. Every language is going to be different.

Calling imported module functions directly in elixir

I have just started learning Elixir and I am unable to figure out how import works in Elixir.
When I import a module into another module using import I am unable to call the imported function by using the module in which it is imported.
But I am able to call function of imported module inside function in the module which it was imported.
defmodule A do
def func do
IO.puts("func called")
end
end
defmodule B do
import A
end
A.func # o/p: "func called"
B.func # (UndefinedFunctionError) undefined function: B.func/0
defmodule B do
import A
def func2 do
func
end
end
B.func2 # o/p "func called"
I am unable to figure out why B.func not works while I was able to call func from func2. Is there some kind of theory that I am missing. Coming from the Ruby background this behaviour looks odd to me. Please can anybody help me out or point me to some good resource to read.
import does not really import anything in the way many other languages do. All it does is makes the imported module's exported functions accessible from the current namespace. To quote the docs
We use import whenever we want to easily access functions or macros from other modules without using the fully-qualified name.
If you want A.func and B.func to point to the same function you have a couple options. The first is simple - make a wrapper function:
defmodule B do
def func do
A.func
end
end
If you want some more complex inheritance type stuff you can look into creating a __using__ macro with defoverridable and super

Import functions in Matlab for every local function

I have an m-file with a couple of tests defined as local functions. They are called from the main function:
function tests = main_function_test()
tests = functiontests(localfunctions);
end
I am doing assertions with some tolerance, so I need to import in each local function:
import matlab.unittest.constraints.IsEqualTo;
import matlab.unittest.constraints.AbsoluteTolerance;
in order to make assertions of the form:
verifyThat(testCase, actual, IsEqualTo(expected, ...
'Within', AbsoluteTolerance(0.00001)));
Is it possible to import those functions just once so they can be reused in each local function?
This is not possible per the documentation:
Scope is the function and the function does not share the import list of the parent function. If the import list is needed in a MATLAB function or script and in any local functions, you must call the import function for each function.
That being said, you could use eval with the output from import (cell array of strings) but it's extremely poor coding practice and I highly recommend against doing it.
function trialcode
import matlab.unittest.constraints.IsEqualTo;
import matlab.unittest.constraints.AbsoluteTolerance;
importlist = import;
sub1(importlist)
end
function sub1(L)
for ii = 1:length(L)
estr = sprintf('import %s', L{ii});
eval(estr);
end
disp(import)
end
Again, this is technically possible but please don't do it this way. You have little control over the imports (and controlling logic would likely be longer than implicitly importing them in the first place), it's difficult to debug, impossible for MATLAB's compiler to optimize, and makes the code tremendously unclear.
There are two things you can do here.
Use the verifyEqual function (doc) to get most of the functionality you have with verifyThat. Note that there exists the 'RelTol' and 'AbsTol' name value pairs with that function.
Define special local functions to use like import statements. These will have precedence within the file just like you would expect from a file level import.
This looks like so:
function tests = main_function_test()
tests = functiontests(localfunctions);
end
function firstTest(testCase)
testCase.verifyThat(actual, IsEqualTo(expected, ...
'Within', AbsoluteTolerance(0.00001)));
end
function testASecondThing(testCase)
testCase.verifyThat(actual, IsEqualTo(expected, ...
'Within', RelativeTolerance(0.0005)));
end
% "import" functions
function c = IsEqualTo(varargin)
c = matlab.unittest.constraints.IsEqualTo(varargin{:});
end
function t = AbsoluteTolerance(varargin)
t = matlab.unittest.constraints.AbsoluteTolerance(varargin{:});
end
function t = RelativeTolerance(varargin)
t = matlab.unittest.constraints.RelativeTolerance(varargin{:});
end
Hope that helps!

Elixir: generating module with proper import

I'm trying to write the macro that generates a module:
defmodule GenModules do
defmacro module(name, do: body) do
quote do
defmodule unquote(String.to_atom(name)) do
unquote(body)
end
end
end
end
What I'm missing is to how to inject the 'import' statement that would refer the module the macro will be called from?
I.e., the following code:
defmodule Test do
import GenModules
module "NewModule" do
def test_call do
hello_world
end
end
def hello_world do
IO.puts "Hello"
end
end
won't compile because hello_world function is not visible from the generated NewModule.
So I need to generate
import Test
before the body of the module, somehow getting the name of the module the macro was called from. How do I do this?
Thank you,
Boris
To get the module your macro was called from you can use the special form __CALLER__. It contains a bunch of information, but you can extract the calling module like so:
__CALLER__.context_modules |> hd
But more generally I don't think what you want is possible - you cannot import a module before you finish defining it. For example:
defmodule A do
defmodule B do
import A
end
end
results in an error:
** (CompileError) test.exs:3: module A is not loaded but was defined.
This happens because you are trying to use a module in the same context it is defined.
Try defining the module outside the context that requires it.