воскресенье, 24 июля 2011 г.

Треугольная периодическая функция

Задача. Есть алгоритм, работающий с некоторым рядом значений. Нужно учесть периодичность следующего характера: например, 1, 2, 1, но не 1, 2, 0; значения в общем случае действительные, целочисленные использованы здесь для простоты). Т. е. нужна функция, принимающая на вход значение без учета периодичности и возвращающая корректное значение с учетом периодичности, так, чтобы возвращаемое значение принадлежало валидному диапазону.

Не сложно догадаться, что функция с указанными свойствами имеет треугольную форму - рост, спад, рост, спад и т. д.

Не буду долго тянуть - далее код, выполняющий задачу и пояснения, как он работает и почему именно так.

/*!
 Represents triangular periodic function with shape 
 {min, min}, {max, max}, {min, min} and period equal to 2*(max - min).
 Third parameter are value that needs to be bound 
 within min and max using periodic nature of function.
*/
inline float TriangularPeriodicFunction(float min, float max, float val)
{
 // shifting coordinate system so function is above x axis now
 // (and performing inverse shift when result is obtained)
 if (min < 0)
  return TriangularPeriodicFunction(0, max - min, val - min) + min;

 // function is symmetric relative to axis of values
 val = fabs(val);
 
 // length of monotonous interval (MI)
 float len = max - min;
 // index of MI
 int d = (int) floor(val/len);
 // index of value within MI
 float m = fmod(val, len); 

 if (d >= 0)
  // MI is at the right side (relative to the y axis)
  return d&1 
   ? max - m // values within MI are decreasing
   : m; // values within MI are increasing
 else
  // MI is at the left side (relative to the y axis)
  return d&1 
   ? m - max // values within MI are increasing
   : m; // values within MI are decreasing
}

Сначала производится сдвиг системы координат, так, чтобы график оказался над осью абсцисс - пример ниже. Это необходимо для однозначного определения положения интервала относительно оси значений.

До преобразования (функция с минимумом -2, максимумом 2):

После преобразования:

После этого определяется индекс монотонного интервала (МИ) с целью узнать - возрастает ли он, или убывает.

А далее все совсем просто: если МИ возрастает, то необходимо вернуть значение, взятое по модулю длины интервала (назовем его M), иначе вернуть то же значение за вычетом максимума (MAX) для интервала, находящегося слева от оси значений или разность MAX - M для интервала, находящегося справа от оси значений. В конце, если нужно, производится обратный сдвиг системы координат (первая-вторая строки кода функции).

Код протестирован и работает для действительных чисел.

четверг, 21 июля 2011 г.

Visual Studio: доверяй, но проверяй... себя!

В предыдущем посте я выразил недоверие к Visual Studio's Clean Solution. Я был не прав - нужно было проверить настройки Configuration Manager, где следует отметить все проекты, подлежащие сборке при построении билда решения.


Дело в том, что ранее я и не заглядывал в эти настройки, хотя знаком со Студией довольно давно - по умолчанию во всех решениях, с которыми доводилось работать, собирались все проекты. Но, как оказалось, в крупных решениях действительно очень удобно отключить сборку проектов, над которыми работа не ведется в данный момент - это ускорит процесс сборки для всего решения. Что же, будем знать! :)

вторник, 19 июля 2011 г.

Visual Studio: когда Clean Solution не помогает

UPD. На самом деле все ОК - подробнее в этом сообщении.

Сегодня столкнулся со странной проблемой: после внесения изменений в код проекта, использующего ASP.NET MVC, и полного ребилда сервер (для отладки использовался локальный IIS) исполнял старую версию.

Очистил решение, собрал - результат тот же, и если поставить брейкпоинт где-нибудь, то он деактивируется по причине вроде "The breakpoint will not currently be hit. The source code is different then the original version.".

Решение проще простого - вручную удалить папку bin и пересобрать проект. Почему я не применил его сразу, а потратил время на копание в настройках проекта и документации? Доверял среде, выполняя Clean Solution. Вот так - доверяй, но проверяй.

суббота, 2 июля 2011 г.

Visual Studio 2010: невозможно заново подключить System.Core.dll

Недавно столкнулся с тем, что в MSVS 2010 невозможно заново подключить System.Core.dll в проект. Оказывается, это известная проблема. Решение - добавить нужную ссылку вручную, открыв файл проекта в текстовом редакторе:
<ItemGroup>
    ...
    <Reference Include="System" />
    <Reference Include="System.Core" />
    ...
</ItemGroup>

пятница, 1 июля 2011 г.

CUDA 4.0: решение проблем при сборке примеров

Честно следуя инструкциям из NVIDIA CUDA C Getting Started Guide for Microsoft Windows, я дошел до пункта "Verify The Installation", где предлагается скомпилировать примеры и запустить bandwidthTest.

Отлично, открываю файл решения для Студии 2010, и запускаю построение. Результат - ошибка: при линковке не найден shrUtils32D.lib.

Обзор папки, в которой размещается SDK (\NVIDIA GPU Computing SDK 4.0), позволил найти shrUtils_vs2010.sln (\NVIDIA GPU Computing SDK 4.0\shared), но при его построении тоже возникли ошибки - не был найден stopwatch.cpp, а также stopwatch_win.cpp. Решение несложное - найти эти файлы в содержимом SDK и добавить их в проект.

После этого shrUtils успешно компилируется и можно вернуться к исходной задаче - сборке примеров, которая теперь также выполняется успешно, позволяя запустить bandwidthTest, что является подтверждением правильной установки SDK и готовности системы к разработке.

Таким образом, нужно выполнить следующие шаги (используется VS 2010):
  1. Открыть решение shrUtils_vs2010.sln.
  2. Добавить в него stopwatch.cpp, а также stopwatch_win.cpp (искать в содержимом SDK).
  3. Собрать решение shrUtils_vs2010.sln.
  4. Открыть решение bandwidthTest_vs2010.sln и собрать его.
  5. Запустить приложение bandwidthTest и убедиться в корректности его работы.