Mercurial > hg > ltpda
diff m-toolbox/classes/@ao/fromPolyval.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m-toolbox/classes/@ao/fromPolyval.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,284 @@ +% FROMPOLYVAL Construct an ao from polynomial coefficients +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% +% FUNCTION: fromPolyval +% +% DESCRIPTION: Construct an ao from polynomial coefficients +% +% CALL: a = fromPolyval(a, vals) +% +% PARAMETER: pl: plist containing 'polyval', 'Nsecs', 'fs', or 't' +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +function a = fromPolyval(a, pli) + + VERSION = '$Id: fromPolyval.m,v 1.27 2011/08/15 05:57:20 hewitson Exp $'; + + import utils.const.* + + % get AO info + ii = ao.getInfo('ao', 'From Polynomial'); + + % Set the method version string in the minfo object + ii.setMversion([VERSION '-->' ii.mversion]); + + % Add default values + pl = applyDefaults(ii.plists, pli); + + coeffs = find(pl, 'polyval'); + Nsecs = find(pl, 'Nsecs'); + fs = find(pl, 'fs'); + t = find(pl, 't'); + x = find(pl, 'x'); + f = find(pl, 'f'); + dtype = find(pl, 'type'); + + % Collect the coefficients + coeff_class = class(coeffs); + + switch coeff_class + case 'ao' + if numel(coeffs) == 1 + % Single AO with an array of coefficients + coeffs = coeffs.y; + else + % Vector of AOs with single coefficients + error(['### Incorrect container for coefficients. \n' ... + 'Supporting only aos, aos inside Nx1 or 1xN matrix object, single pest objects, double arrays']); + end + case 'matrix' + % A matrix of AOs with single coefficients + coeff_array = [ao]; + ncol = ncols(coeffs); + nrow = nrows(coeffs); + if ncol > 1 + if nrow == 1 + nc = ncol; + for jj = 1:nc + coeff_array(jj) = coeffs.getObjectAtIndex(1, jj); + end + coeffs = coeff_array.y; + else + error(['### Incorrect container for coefficients. \n' ... + 'Supporting only aos, aos inside Nx1 or 1xN matrix object, single pest objects, double arrays']); + end + else + nc = nrow; + for jj = 1:nc + coeff_array(jj) = coeffs.getObjectAtIndex(jj, 1); + end + coeffs = coeff_array.y; + end + case 'pest' + nc = numel(coeffs.y); + if numel(coeffs) == 1 + % Single pest with an array of coefficients + if ~isempty(coeffs.models) + yunits = coeffs.models.yunits; + else + yunits = []; + end + coeff_yunits = coeffs.yunits; + coeffs = coeffs.y; + else + % Vector of pests with single coefficients + error(sprintf(['### Incorrect container for coefficients. \n' ... + 'Supporting only aos, aos inside Nx1 or 1xN matrix object, single pest objects, double arrays'])); + end + case 'double' + % Do nothing in this case + otherwise + error(sprintf(['### Incorrect container for coefficients. \n' ... + 'Supporting only aos, aos inside Nx1 or 1xN matrix object, single pest objects, double arrays'])); + end + + % Try to decide what to do if the user doesn't specify data type + if isempty(dtype) + if ~isempty(Nsecs) || ~isempty(t) || ~isempty(fs) + dtype = 'tsdata'; + elseif ~isempty(x) + dtype = 'xydata'; + elseif ~isempty(f) + dtype = 'fsdata'; + else + error('### Please specify data type and parameters'); + end + end + + switch dtype + case 'tsdata' + if isa(t, 'ao') + t_xunits = t.xunits; + % Override the xunits by using those from the t vector + utils.helper.msg(msg.OFF, ... + 'warning: overriding the user-input xunits %s with the t ao %s', ... + char(find(pl, 'xunits')), char(t_xunits)); + t = t.x; + else + t_xunits = []; + end + + % Check t vector + if isempty(t) + if isempty(Nsecs) || isempty(fs) + error('Please provide either ''Nsecs'' and ''fs'', or ''t'' for polyval constructor with data type ''tsdata''.'); + end + t = 0 : 1/fs : Nsecs-1/fs; %t = linspace(0, Nsecs - 1/fs, Nsecs*fs); + end + + y = polyval(coeffs,t); + + % Make a tsdata object + p = tsdata(t, y); + + % Make sure the actual sampling frequency fs is captured in the plist + pl.pset('fs', p.fs); + + % set T0 + p.setT0(pl.find('t0')); + + % set Toffset + if ~isempty(pl.find('toffset')) + toffset = p.toffset + 1000*pl.find('toffset'); + p.setToffset(toffset); + end + + % Checks the units + % xunits + if isempty(t_xunits) + new_xunits = find(pl, 'xunits'); + if isempty(new_xunits) + new_xunits = 's'; + end + else + new_xunits = t_xunits; + end + pl.pset('xunits', new_xunits); + + case 'xydata' + if isa(x, 'ao') + x_xunits = x.xunits; + % Override the xunits by using those from the x vector + utils.helper.msg(msg.OFF, ... + 'warning: overriding the user-input xunits %s with the x ao %s', ... + char(find(pl, 'xunits')), char(x_xunits)); + pl.pset('xunits', x_xunits); + x = x.x; + else + x_xunits = []; + end + + % Check x vector + if isempty(x) + error('### Please provide the x values'); + end + + y = polyval(coeffs,x); + + % Make a xydata object + p = xydata(x, y); + + % Checks the units + % xunits + if isempty(x_xunits) + new_xunits = find(pl, 'xunits'); + else + new_xunits = x_xunits; + end + pl.pset('xunits', new_xunits); + + case 'fsdata' + if isa(f, 'ao') + f_xunits = f.xunits; + % Override the xunits by using those from the x vector + utils.helper.msg(msg.OFF, ... + 'warning: overriding the user-input xunits %s with the x ao %s', ... + char(find(pl, 'xunits')), char(f_xunits)); + pl.pset('xunits', f_xunits); + f = f.x; + else + f_xunits = []; + end + + % Check f vector + if isempty(f) + error('### Please provide the frequency values'); + end + + y = polyval(coeffs,f); + + % Make a fsdata object + p = fsdata(f, y); + + % Checks the units + % xunits + if isempty(f_xunits) + new_xunits = find(pl, 'xunits'); + if isempty(new_xunits) + new_xunits = 'Hz'; + end + else + new_xunits = f_xunits; + end + pl.pset('xunits', new_xunits); + + otherwise + error('### Unsupported data type %s', dtype); + end + + % yunits + switch lower(coeff_class) + case 'matrix' + % Matrix of AOs with coefficients was provided. So the units must be + % consistent (with requested, if any, and between each other) + new_yunits = find(pl, 'yunits'); + if isempty(new_yunits) + new_yunits = simplify(coeff_array(1).yunits .* (new_xunits.^(nc-1))); + else + new_yunits = unit(new_yunits); + end + for jj = 1:nc + if coeff_array(jj).yunits * (new_xunits.^(nc-jj)) ~= new_yunits + error('### Inconsistent units either between coefficients or with requested') + end + end + pl.pset('yunits', new_yunits); + case 'pest' + % A pest object with coefficients was provided + % Did the user provide yunits? Let's use them + new_yunits = find(pl, 'yunits'); + % Otherwise, let's use the yunits of the smodel inside the pest + if isempty(new_yunits) + new_yunits = yunits; + end + % Otherwise, let's calculate them + if isempty(new_yunits) + new_yunits = simplify(coeff_yunits(1) .* (new_xunits.^(nc-1))); + for jj = 1:nc + if simplify(coeff_yunits(jj) * (new_xunits.^(nc-jj))) ~= new_yunits + error('### Inconsistent units either between coefficients') + end + end + end + pl.pset('yunits', new_yunits); + otherwise + end + + % Make an analysis object + a.data = p; + % Set xunits + a.setXunits(pl.find('xunits')); + % Set yunits + a.setYunits(pl.find('yunits')); + % Simplify units + a.simplifyYunits(plist('Prefixes', false)); + % Add history + a.addHistory(ii, pl, [], []); + % Set object properties from the plist + a.setObjectProperties(pl); + + + +end +