Functions and Time Histories


A function is a series of data pairs (x,y). A function can be visualized on an XY plot. The x values are referred to as the abscissa, and the y values are the ordinate. The abscissa values must always be real-valued, whereas the ordinate can take arbitrary values, real or complex.

Data attributes are stored with each function to capture additional information (coordinate labels, data types, descriptive text labels, etc.). In I-deas, these data attributes can be accessed in the function selection form via the "Data Attributes" button. When you acquire test data in I-deas, many data attributes are set for you from the channel table and the setup of the data acquisition. Using the IMAT toolbox, you will be able to access the data attributes while in MATLAB.

First a word about the distinction between functions and time histories. I-deas treats functions and time histories as distinct data types. Functions are stored in function ADFs (extension .afu), while time histories are stored in time history ADFs (extension .ati). Actually, for most purposes a time history is just a special class of functions for which the abscissa is time, and the ordinate is real. Time histories can be stored in function ADFs, but most types of functions cannot be stored in time history ADFs. Siemens NX supports function ADFs (.afu).

Because of the similarities, the IMAT toolbox treats functions and time histories as a common data type. The distinction is necessary only when reading from or writing to an ADF, when you must use the proper file extension. The rest of this document will refer generically to functions, with the understanding that time histories are included as a special case.

IMAT+FEA utilizes the imat_fn data type for function and time history data imported from NASTRAN and Abaqus files. In these cases not all of the attributes available in the imat_fn object are applicable, but using this data type offers consistency within MATLAB.

Data Format for Functions

In MATLAB, the IMAT toolbox stores both the function data (abscissa and ordinate values) and the data attributes in a single MATLAB variable. This variable is marked as an imat_fn object, which tells MATLAB to use special methods to operate on it. The main advantage of this combined storage format is that it keeps you from losing the association between a function's data and its associated attributes.

To get started, you can see the full list of function attributes with the set function (described in more detail later):

>> set(imat_fn)

FunctionType: [ General | Time Response | Auto Spectrum
| Cross Spectrum | Frequency Response Function | Transmissibility
| Coherence | Auto Correlation | Cross Correlation
| Power Spectral Density | Energy Spectral Density
| Probability Density Function | Spectrum
| Cumulative Frequency Distribution | Peaks Valley | Stress/Cycles
| Strain/Cycles | Orbit | Mode Indicator Function | Force Pattern
| Partial Power | Partial Coherence | Eigenvalue | Eigenvector
| Shock Response Spectrum | Finite Impulse Response Filter
| Multiple Coherence | Order Function | Phase Compensation
| Harmonic Function | Octave | Temperature | Stress vs Strain
| Life | Campbell Diagram ]OwnerName: [ char string length 16 ]
Version: [ integer value ]
SetRecord: [ integer value ]
ResponseCoord: [ coordinate string ]
ResponseNode: [ integer value ]
ResponseDir: [ char string length 4 ]
ReferenceCoord: [ coordinate string ]
...

OctaveAvgType: [ None | Fast | Slow | Impulse | Linear ]
ExpDampingFact: [ real value ]
PulsesPerRev: [ real value ]
MeasurementRun: [ real value ]
IRIGTime: [ char string length 19 format DDD:HH:MM:SS.SSSSSS ]

The specific meaning of each data attribute can be found in the reference section. In general, you will have access to the abscissa, the ordinate, and three types of attributes:

You will see later how to examine and modify the function values and data attributes. Before we do, you will need to understand how functions are grouped together.

Arrays of Functions

IMAT allows you to combine multiple functions in arrays of functions.

An easy way to get such an array of functions is to read data from an ADF or universal file. If there are multiple records in the file, they will be stacked in a MATLAB column vector, each element of which is an individual IMAT Function. The following example reads functions from a universal file:

>> f=readunv('testdata.unv')
Read 6x1 imat_fn
Will read data in SI

f =

6x1 IMAT Function with the following attributes:
Record Name       FunctionType     AbscissaSpacing  NumberElements
----------------- ---------------- ---------------- --------------
1_(100Z+,1Z+)     Frequency Respon Even             801
2_(1Z+,1Z+)       Auto Spectrum    Even             801
3_(100Z+,2Z+)     Frequency Respon Even             801
4_(2Z+,2Z+)       Auto Spectrum    Even             801
5_(100Z+,3Z+)     Frequency Respon Even             801
6_(3Z+,3Z+)       Auto Spectrum    Even             801

>>

In this example, the MATLAB variable f is actually a 6x1 array of functions. Each element in f is itself a distinct imat_fn, and there is no requirement that the functions have the same size or compatible data attributes. Each element of f has its own unique function values and data attributes.

You can access individual functions in an array of functions using the same index options you use for numeric arrays in MATLAB. For the example function above, f(3) refers to the third record (reference 100Z+ and response 2Z+), and f(4:6) is an array containing the last three records of f. Or you can manipulate subsets of function arrays like matrix elements:

>> g=f;
>> g(3:4)=f(5:6)

g =

6x1 IMAT Function with the following attributes:
Record Name       FunctionType     AbscissaSpacing  NumberElements
----------------- ---------------- ---------------- --------------
1_(100Z+,1Z+)     Frequency Respon Even             801
2_(1Z+,1Z+)       Auto Spectrum    Even             801
3_(100Z+,3Z+)     Frequency Respon Even             801
4_(3Z+,3Z+)       Auto Spectrum    Even             801
5_(100Z+,3Z+)     Frequency Respon Even             801
6_(3Z+,3Z+)       Auto Spectrum    Even             801

>>

You are not restricted to just column vectors of functions, though this is the most common arrangement. An imat_fn can be two dimensional (rows and columns) like a matrix of functions, or could even have more than two dimensions.

Creating a Function in MATLAB

To create an imat_fn from scratch, you use the imat_fn constructor as in the following examples:

>> f=imat_fn(3);    % Creates 3x1 column vector of functions
>> f=imat_fn(2,3);  % Creates 2x3 matrix of functions

The functions are created with no abscissa/ordinate values, and with default data attributes. After you create the function, you will want to set its attributes and data values. Click here to see how to do this.

Importing Functions

There are three ways to get function (or time history) data from I-deas or other software package into MATLAB.

Direct ADF access with readadf

You can directly read the contents of a function ADF (filename *.afu) or a time history ADF (filename *.ati) using the readadf function. This function accepts an optional filename argument of the file to read. If the filename is omitted or contains wildcards, then the user will be prompted for the file to read. Here is an example:

>> f=readadf('testdata.ati')
ADF Name: /users/imatdemo/testdata.ati
Units   : <7> IN
Begin processing...
  5 records processed...
End processing...

f =

5x1 IMAT Function with the following attributes:
Record Name       FunctionType     AbscissaSpacing  NumberElements
----------------- ---------------- ---------------- --------------
1_(,101X+)        Time Response    Even             801
2_(,101Y-)        Time Response    Even             801
3_(,98)           Time Response    Even             801
4_(,12X-)         Time Response    Even             801
5_(,12Y+)         Time Response    Even             801
>>

Universal file import with readunv

The IMAT toolbox allows you to read a wide variety of universal files. Universal files are generally ASCII text files that can be read and written by a number of software packages. There are also binary universal file formats available for functions and time histories.

To read a universal file containing datasets 58 into MATLAB, use the readunv function in the IMAT toolbox. The calling sequence is the same as for readadf. You can provide a filename argument, or call readunv with a wildcard or no argument to interactively select the file to read.

Universal files provide a way to move function data from one platform to another. Use any text file transfer utility (such as FTP) to copy the file. Binary universal files (dataset 58b) can also be transported across platforms, but you should be sure to use a binary file transfer protocol.

Abaqus ODB file import with readodb

The IMAT+FEA extended functionality allows you to read xyData and histories from steps in an Abaqus ODB file using readodb. These functions will be imported as imat_fn. The Abaqus xyData and historyObject attributes will be mapped as best as possible into the imat_fn attributes.

Exporting Functions

Similar to importing, you have two options for transmitting function data to other software package.

Direct ADF access with writeadf

You can directly write one or more imat_fn variables into a function ADF or a time history ADF (if appropriate) using the writeadf function. This function takes a filename argument and one or more imat_fn arguments. If the filename contains wildcards, then the user will be prompted for the file to write. Here is an example:

>> writeadf('testdata.afu',f)
>>
ADF Name: /users/imatdemo/testdata.afu
Units   : <7> IN
  Writing 'f' (34 records)...

If the specified ADF already exists, the new records will be appended after any existing records in the file.

Universal file export with writeunv

You can create either ASCII or binary universal files (dataset 58 or 58b) using the writeunv function in the IMAT toolbox. The arguments to writeunv are the same as for writeadf. The first argument is a filename, which can be a wildcard. The remaining arguments are one or more imat_fn variables to be written to the universal file.

To write a binary universal file, you must provide a first argument of 'binary'. This argument is followed by the filename and imat_fn arguments.

If you copy the universal file to a different platform, you should be sure to use an ASCII file transfer protocol so that carriage returns get converted properly. Binary universal files should be copied with a binary file transfer protocol.

Accessing Function Data and Attributes

IMAT offers two methods for you to examine or modify the contents of an imat_fn.

Reading attributes and data

The simplest way to get information about a function is with the syntax f.attrib, where f is the name of the variable, and attrib is the name of the attribute you want. The possible attribute names are listed in the reference section of this document, or you can get a listing with the set function. Here are some examples:

>> f.abscissamin

ans =

    0
    0
    0
    0
    0
    0

>> f.abscissaspacing

ans =

    'Even'
    'Even'
    'Even'
    'Even'
    'Even'
    'Even'

These examples illustrate that numeric attributes like AbscissaMin are returned in a numeric array the same size as f. String-valued attributes like AbscissaSpacing as well as list attributes are returned either as a character string (if f is a single function) or in a cell array of strings if f is a vector or array of functions. (For more information on cell arrays and cell arrays of strings, consult the MATLAB documentation.)

Data attributes return a single numeric or string value for each element of a function array. The abscissa and ordinate "attributes", on the other hand, each return an array of values for each element of the function array. When you ask for the ordinate you will get a multidimensional array whose first dimension corresponds to the ordinate elements, and whose remaining dimensions match the size of the imat_fn array. For the example we've been following above, the statement

x=f.ordinate

will set x to an 801x6 numeric array, since all of the elements of f have 801 ordinate elements. The first column of x is the ordinate for f(1), and so on. If f had been a 5x3 array of functions, then x would have been an 801x5x3 multidimensional numeric array.

The same thing happens when you access the abscissa: an extra dimension is added as the first dimension of the result. Note: abscissa values are returned even if the function is evenly spaced. Evenly spaced functions do not actually store the abscissa, but the abscissa values are constructed when requested.

What do you get from f.abscissa or f.ordinate if the functions in f are not equal in length? In this case, IMAT sets the first dimension of the result (abscissa or ordinate) to the largest of any of the functions in the array. For those functions with less data than the maximum, the extra abscissa and ordinate values are filled with NaN (i.e., "not a number") values.

An alternative way to access function information is with get. In general, the expression get(f,'attrib') is equivalent to the expression f.attrib as discussed above. However, the get function also allows you to extract multiple attributes in one call. Here's an example:

>> r=get(f,'abscissamin','abscissainc','functiontype')

r =
   AbscissaMin: [6x1 double]
  FunctionType: {6x1 cell}
   AbscissaInc: [6x1 double]

>>

When you ask for multiple attributes, get returns a structure with field names equal to the attributes you selected. The value in each field is the value of the corresponding attribute, as discussed above. If you do not specify any attributes at all, then get will return all of the data attributes. After a call to get, you can refer to the individual returned values by name, provided you use the proper combination of upper and lower case to refer to the fields:

>> r.AbscissaMin

ans =
    0
    0
    0
    0
    0
    0
>>

Changing attributes and data

To change an attribute of a function, you use the syntax f.attrib=value. Numeric attributes should be set to a numeric array with dimension matching f. String-valued attributes and list attributes should be set to a cell array of strings, and the cell array should be the same dimension as f. The ordinate and abscissa should have an extra first dimension as discussed above.

A special case is made for times when you want to set all functions in an imat_fn array to have the same attribute. In this case, you can set the value to be a scalar numeric value or a simple character string. The same value will then be applied to all of the functions in the array. If you set the abscissa or ordinate to a single column vector, then the same vector is used for all elements of f.

Here are some examples of attribute manipulations:

>> f=imat_fn(3);                      % Make f a 3x1 imat_fn
>> f.ordinate=rand(5,3);              % Set random ordinate values
>> f(2:3).referencecoord={'2x';'3x'}; % Set coords with cell array
>> f.ordnumdatatype='acceleration';   % Set all data types to acceleration
>> f.responsenode=[1001;1002;1003];   % Set node labels to 1001-1003

The set function is an alternative way to change attributes or function data. The syntax is g=set(f,'attrib',value,...). You can set one or many attributes. The result g is a duplicate of f, with the exception of the attributes you specify. set also accepts a structure, like the one that get returns. For example,

>> r=get(f(1),'functiontype','referencecoord','responsecoord')

r =

    FunctionType: 'Frequency Response Function'
   ResponseCoord: {1x1  cell}
  ReferenceCoord: {1x1  cell}

>> f=set(f,r)

f =

6x1 IMAT Function with the following attributes:
Record Name       FunctionType     AbscissaSpacing  NumberElements
----------------- ---------------- ---------------- --------------
1_(100Z+,1Z+)     Frequency Respon Even             801
2_(100Z+,1Z+)     Frequency Respon Even             801
3_(100Z+,1Z+)     Frequency Respon Even             801
4_(100Z+,1Z+)     Frequency Respon Even             801
5_(100Z+,1Z+)     Frequency Respon Even             801
6_(100Z+,1Z+)     Frequency Respon Even             801
>>

The function type, reference, and response coordinate attributes of all six functions in f have been changed to match the corresponding attributes of f(1).

Function Selection

It is often necessary to select a subset of functions from a function array. For example, you may want to select frequency response functions from a particular reference coordinate. Or you may want to look only at time histories from acceleration channels. IMAT offers two convenient techniques for function selection: coordinate trace selection and filter selection.

Selecting functions by coordinate trace

Each function record in I-deas (or each element of a function array in MATLAB) is identified by its reference and response coordinates. (In some cases the reference coordinate may be null.) You can extract elements of a function array based on the response coordinate identifiers. This is done using the syntax f{trace}, where f is the imat_fn array and trace is either a coordinate trace variable or a list of coordinate strings. More information on coordinate traces in IMAT can be found here.

Here are some representative examples of function selection using coordinate traces, assuming testdata is an imat_fn array:

>> x_accel=testdata{'101x-'};
>> strain_trace=imat_ctrace('11x','12x','13x','14x');
>> strains = testdata{strain_trace};

When you select functions by coordinate trace, you will obtain exactly one function for each element of the coordinate trace (and the functions in the result will be in the same order as the coordinate trace). If more than one function in the array has a given response coordinate, only the first match will be returned. If any coordinate in the coordinate trace cannot be found in the function, an error will result.

It is also possible to select functions based on reference/response pairs. The syntax for this option is f{ref_trace,res_trace}, where f is the imat_fn array, and ref_trace and res_trace are imat_ctrace variables. The result of this syntax is a two-dimensional function array with rows matching the reference coordinates in ref_trace, and columns matching the response coordinates in res_trace. Here is an example:

>> f=readadf('testdata.afu')
ADF Name: /users/imatdemo/testdata.afu
Units   : <7> IN
Begin processing...
75 records processed...
End processing...

f =

75x1 IMAT Function with the following attributes:
Record Name       FunctionType     AbscissaSpacing  NumberElements
----------------- ---------------- ---------------- --------------
1_(1X+,1X-)       Frequency Respon Even             1601
2_(1X+,2X-)       Frequency Respon Even             1601
3_(1X+,3X-)       Frequency Respon Even             1601
4_(1X+,101Y+)     Frequency Respon Even             1601
5_(1X+,101Z-)     Frequency Respon Even             1601
6_(1X+,101X-)     Frequency Respon Even             1601
7_(1X+,401Z-)     Frequency Respon Even             1601
8_(1X+,401Y-)     Frequency Respon Even             1601
...
71_(2Y-,2X-)      Frequency Respon Even             1601
72_(2Y-,3X-)      Frequency Respon Even             1601
73_(3X+,1X-)      Frequency Respon Even             1601
74_(3X+,2X-)      Frequency Respon Even             1601
75_(3X+,3X-)      Frequency Respon Even             1601

>> ref=imat_ctrace('1x','2y-');
>> res=imat_ctrace('101x','101y','101z-');
>> frf = f{ref,res}

frf =

2x3 IMAT Function with the following attributes:
Row Col Record Name      FunctionType     AbscissaSpacing  NumberElements
--- --- ---------------- ---------------- ---------------- --------------
1   1   1_(1X+,101X+)    Frequency Respon Even             1601
2   1   2_(2Y-,101X+)    Frequency Respon Even             1601
1   2   3_(1X+,101Y+)    Frequency Respon Even             1601
2   2   4_(2Y-,101Y+)    Frequency Respon Even             1601
1   3   5_(1X+,101Z-)    Frequency Respon Even             1601
2   3   6_(2Y-,101Z-)    Frequency Respon Even             1601
>>

This type of function array is very useful for some types of modal analysis. In the above example, frf.ordinate would return a 1601x2x3 array of FRF values vs. frequency, reference, and response.

Note that for the reference/response selection to work, the coordinate traces in the braces must be actual imat_ctrace variables. For example, f{'1x','2x'} will look for response coordinates equal to '1x' and '2x', rather than returning a single function with reference coordinate '1x' and response coordinate '2x'. Also, you will get an error if any of the reference/response pairs are not present in the function array.

Selection by filter

Another powerful selection method makes use of "filters". A filter (in this context) refers to a set of selection criteria. For a more complete discussion of filters, click here.

To use a filter to select functions, you use the syntax f{filter}. The filter in braces can either be an imat_filt variable (which allows for fairly complicated filter criteria), or can be a simple filter expression using 3 inputs. Here are some examples of both types of expressions:

>> g = f{'functiontype', '=', 'frequency response function'};
>> g = f{'responsenode', '~=', 1000};
>> z1 = imat_filt('functiontype', '=', 'time response');
>> z2 = imat_filt(imat_fn,'responsecoord', '=', '101*');
>> g = f{z1&z2};

The first example selects all frequency response functions. The second example selects all functions except those with a response node of 1000. The third example selects time histories whose response coordinate starts with 101.

You can write a filter criterion for reference or response coordinates being members of a coordinate trace. Consider this example:

>> t = imat_ctrace('101x','102y');
>> g = f{'responsecoord', '=', t};

The function g will have all elements of f whose response coordinate is either 101X or 102Y. This is slightly different than using coordinate trace selection. In this case, all elements of f that match the criterion will be returned, and the records will be in their original order.

Math Operations

You can perform any MATLAB operation on an imat_fn simply by extracting its ordinate into a numeric array, performing the desired operation, and creating a new imat_fn with the resulting ordinate. However, some operations can be performed directly on imat_fn objects, using methods built into IMAT. Here is a summary of the available operations:

Unary Operations
+f Unary plus (leaves f unchanged)
-f Unary minus (negate the ordinate of f)
real(f) Take real part of the ordinate of f
imag(f) Take imaginary part of the ordinate of f
conj(f) Take complex conjugate of the ordinate of f
abs(f) Take absolute value of the ordinate of f (or modulus if f is complex)
phase(f) Return phase angle of complex ordinate in radians
phased(f) Return phase angle of complex ordinate in degrees
Binary Operations
f+scalar, f-scalar Add, subtract scalar value to all ordinate values
f.*scalar, f./scalar, f.\scalar Multiply or divide function ordinate by scalar value
f+g, f-g Add or subtract two functions. Operation is performed on ordinates of matching array elements of f and g (i.e., f(1)-g(1), f(2)-g(2), etc.)
f.*g, f.\g, f./g Termwise multiply or divide two functions. Operation is performed termwise on ordinates of matching array elements of f and g.
A*f, f/A, A\f Multiply (or divide) matrix A times function f. The matrix operation is performed at all abscissa elements, with f replaced by its ordinate values at that element. The number of rows in the function array f should equal the number of columns of A, and all functions in f should have equal size.


The matrix multiply operations are the most confusing, because of the extra dimension on the ordinate. Matrix multiplication operates on the vector of functions, and is repeated at each ordinate value. Suppose f is a 2x1 imat_fn, and A is 3x2. Then the statement g=A*f creates a 3x1 imat_fn whose attributes match f(1), and whose ordinate is

g(1).ordinate = A(1,1)*f(1).ordinate + A(1,2)*f(2).ordinate
g(3).ordinate = A(3,1)*f(1).ordinate + A(3,2)*f(2).ordinate
g(2).ordinate = A(2,1)*f(1).ordinate + A(2,2)*f(2).ordinate

The multiplication by A is done for each ordinate value. This type of operation is very useful for cases where one set of measurements can be constructed as a linear combination of another set of measurements. The combination is done at every time step (for a time history) or at every frequency (for a frequency response function). Note that you may need to set the ordinate data type and other data attributes on the result of such an operation.

Function Sets

A function set is a group of functions with all data attributes in common except for ordinate values and Z-axis attributes. These are handy for grouping functions together for a waterfall plot, for example.

When you read an ADF containing function sets into MATLAB, the function sets will not be immediately obvious. Each individual function record will show up in the imat_fn variable. However, it is easy to reconstruct individual function sets, because each function set has a unique value of the Set data attribute. For example, to extract function set 2 from an ADF, you can use the following commands:

>> f=readadf('filename.afu');    % Read all records into f
>> f2=f{'set','=',2};            % Select only those records in set 2

Now you could produce a waterfall plot in MATLAB with the commands:

>> freq=f2(1).abscissa;
>> time=f2.ztimevalue;              % Get time values (could also get RPM, etc)
>> mesh(time,freq,f2.ordinate);     % Frequency axis is the same for all

Alternatively, you can create a function set in MATLAB, making sure that all elements of the function have consistent data attributes and abscissa values. Give each function the same Set data attribute (e.g., 1). Then set the Z-axis values for all of the functions. You can then export this function set to I-deas Test (using writeadf or writeunv) and view the waterfall in I-deas.


Previous

Next