- now complex interpolation can also be created using abs and phase
parent 1b4915d0
......@@ -48,20 +48,29 @@ classdef itaComsolFunction < itaComsolNode
obj.setNodeProperties( interpolationNode, propertyStruct );
function [realInterpolationNode, imagInterpolationNode, funcExpression] = CreateComplexInterpolation(obj, interpolationBaseName, freqVector, complexDataVector, functionUnits)
function [interpolationNode1, interpolationNode2, funcExpression] = CreateComplexInterpolation(obj, interpolationBaseName, freqVector, complexDataVector, functionUnits, absPhase)
%Creates or adjusts two Comsol Interpolation nodes, one for the
%real and one for the imaginary data and returns the two
%interpolation nodes.
% The interpolation tags are interpolationBaseName_real and
% interpolationBaseName_imag. The argument units are set to
% Hz whereas the function units are specified by the user.
%real/absolute and one for the imaginary/phase data and returns
%the two interpolation nodes.
% The user can specify the absPhase bool in order to
% interpolate real/imag data or abs/phase data. By default,
% real and imaginary part are interpolated.
% The tags of the result interpolations tags are
% interpolationBaseName_*, where * can be real, imag, abs or
% phase respectively. The argument units are set to Hz
% whereas the function units are specified by the user.
% Default methods are "piecewise cubic" interpolation and
% "linear" extrapolation.
if nargin == 5; absPhase = false; end
if isnumeric(absPhase); absPhase = logical(absPhase); end
assert(ischar(interpolationBaseName) && isrow(interpolationBaseName), 'First input must be a char row vector')
assert(isnumeric(freqVector) && isvector(freqVector) && isreal(freqVector), 'Second input must be a real-valued double vector')
assert(isnumeric(complexDataVector) && isvector(complexDataVector), 'Third input must be a complex-valued double vector')
assert(ischar(functionUnits) && isrow(functionUnits), 'Fourth input must be a char row vector')
assert(numel(freqVector) == numel(complexDataVector), 'Number of elements in frequency and data vector must be equal.')
assert(islogical(absPhase) && isscalar(absPhase), 'Last input must be a logical scalar.')
switch numel(freqVector)
case 0
error('Empty data specified')
......@@ -76,35 +85,55 @@ classdef itaComsolFunction < itaComsolNode
interpolation = 'piecewisecubic'; %'cubicspline'
interpolationNameReal = [interpolationBaseName '_real'];
interpolationNameImag = [interpolationBaseName '_imag'];
propertyStruct1.source = 'table';
propertyStruct1.argunit = 'Hz';
propertyStruct1.fununit = functionUnits;
propertyStruct1.extrap = extrapolation;
propertyStruct1.interp = interpolation;
propertyStruct2 = propertyStruct1;
realInterpolationNode = obj.CreateInterpolation(interpolationNameReal);
imagInterpolationNode = obj.CreateInterpolation(interpolationNameImag);
if absPhase
interpolationName1 = [interpolationBaseName '_abs'];
interpolationName2 = [interpolationBaseName '_phase'];
freqData1 = abs(complexDataVector);
freqData2 = unwrap(angle(complexDataVector));
propertyStruct2.fununit = 'rad';
interpolationName1 = [interpolationBaseName '_real'];
interpolationName2 = [interpolationBaseName '_imag'];
freqData1 = real(complexDataVector);
freqData2 = imag(complexDataVector);
propertyStruct.source = 'table';
propertyStruct.argunit = 'Hz';
propertyStruct.fununit = functionUnits;
propertyStruct.extrap = extrapolation;
propertyStruct.interp = interpolation;
interpolationNode1 = obj.CreateInterpolation(interpolationName1);
interpolationNode2 = obj.CreateInterpolation(interpolationName2);
obj.setNodeProperties(realInterpolationNode, propertyStruct);
obj.setNodeProperties(imagInterpolationNode, propertyStruct);
obj.setNodeProperties(interpolationNode1, propertyStruct1);
obj.setNodeProperties(interpolationNode2, propertyStruct2);
obj.setInterpolationTableData(realInterpolationNode, freqVector, real(complexDataVector));
obj.setInterpolationTableData(imagInterpolationNode, freqVector, imag(complexDataVector));
obj.setInterpolationTableData(interpolationNode1, freqVector, freqData1);
obj.setInterpolationTableData(interpolationNode2, freqVector, freqData2);
funcExpression = obj.GetComplexFunctionExpression(realInterpolationNode, imagInterpolationNode);
funcExpression = obj.GetComplexFunctionExpression(interpolationNode1, interpolationNode2, absPhase);
methods(Static = true)
function expression = GetComplexFunctionExpression(realInterpolationNode, imagInterpolationNode)
function expression = GetComplexFunctionExpression(realOrAbsInterpolationNode, imagOrPhaseInterpolationNode, absPhase)
%Returns a function expression giving two interpolation nodes
%either splitting data in real/imag or abs/phase.
% The expression will look like this:
% tagReal(freq) + i*tagImag(freq)
realFuncName = char(realInterpolationNode.tag);
imagFuncName = char(imagInterpolationNode.tag);
expression = [realFuncName '(freq) + i*' imagFuncName '(freq)'];
% or
% tagAbs(freq) * exp( i*tagPhase(freq) )
if nargin == 2; absPhase = false; end
funcName1 = char(realOrAbsInterpolationNode.tag);
funcName2 = char(imagOrPhaseInterpolationNode.tag);
if absPhase
expression = [funcName1 '(freq) * exp(i*' funcName2 '(freq))'];
expression = [funcName1 '(freq) + i*' funcName2 '(freq)'];
methods(Access = private, Static = true)
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment