def get_power_factor(self, output='eigs', doping_levels=True,
                         relaxation_time=1e-14):
        """
        Gives the power factor (Seebeck^2 * conductivity) in units
        microW/(m*K^2) in either a full 3x3 tensor form,
        as 3 eigenvalues, or as the average value (trace/3.0) If
        doping_levels=True, the results are given at
        different p and n doping levels (given by self.doping), otherwise it
        is given as a series of
        electron chemical potential values

        Args:
            output (string): the type of output. 'tensor' give the full 3x3
            tensor, 'eigs' its 3 eigenvalues and
            'average' the average of the three eigenvalues
            doping_levels (boolean): True for the results to be given at
            different doping levels, False for results
            at different electron chemical potentials
            relaxation_time (float): constant relaxation time in secs

        Returns:
            If doping_levels=True, a dictionnary {temp:{'p':[],'n':[]}}. The
            'p' links to power factor
            at p-type doping and 'n' to the conductivity at n-type doping.
            Otherwise,
            returns a {temp:[]} dictionary. The result contains either the
            sorted three eigenvalues of the symmetric
            power factor tensor (format='eigs') or a full tensor (3x3 array) (
            output='tensor') or as an average
            (output='average').
            The result includes a given constant relaxation time

            units are microW/(m K^2)
        """
        result = None
        result_doping = None
        if doping_levels:
            result_doping = {doping: {t: [] for t in
                                      self._seebeck_doping[doping]} for
                             doping in self._seebeck_doping}

            for doping in result_doping:
                for t in result_doping[doping]:
                    for i in range(len(self.doping[doping])):
                        full_tensor = np.dot(self._cond_doping[doping][t][i],
                                             np.dot(
                                                 self._seebeck_doping[doping][
                                                     t][i],
                                                 self._seebeck_doping[doping][
                                                     t][i]))
                        result_doping[doping][t].append(full_tensor)

        else:
            result = {t: [] for t in self._seebeck}
            for t in result:
                for i in range(len(self.mu_steps)):
                    full_tensor = np.dot(self._cond[t][i],
                                         np.dot(self._seebeck[t][i],
                                                self._seebeck[t][i]))
                    result[t].append(full_tensor)

        return BoltztrapAnalyzer._format_to_output(result, result_doping,
                                                   output, doping_levels,
                                                   multi=1e6 * relaxation_time)